2017-02-08 65 views
1

我在使用knex.js构建查询,并给定现有的子查询。继this答案,并在GitHub上this线程,我试过如下:从knex.js中的现有查询中进行选择

const knex = require("knex")({client: 'pg'}); 

const subQuery = knex.queryBuilder().select(1); 

const query = knex.queryBuilder().select('*').from(subQuery); 

console.log(query.toString()); 

但结果是:

select * from select 1 

这显然有语法错误。我的预期结果是:

select * from (select 1) 

为什么不添加括号,我该如何改变它?

回答

2

你的方式,你怎么做似乎是正确的,我会说这是在knex为什么它不起作用的错误(我是knex合作者)。

反正有几种方法可以做到这一点...

const knex = require("knex")({client: 'pg'}); 

const subQuery = knex.select(1).as('t1'); 
const query = knex.select('*').from(subQuery); 
console.log(query.toSQL()); 

{ method: 'select', 
    options: {}, 
    timeout: false, 
    cancelOnTimeout: false, 
    bindings: [], 
    __knexQueryUid: '69d240ad-f5f8-4bc4-8c1d-fb9432af1da2', 
    sql: 'select * from (select 1) as "t1"' } 

或者你可以使用旧的风格function()子查询,不需要.as(),但支持它...

const query = knex.select('*').from(sq => sq.select(1)); 
console.log(query.toSQL()); 

{ method: 'select', 
    options: {}, 
    timeout: false, 
    cancelOnTimeout: false, 
    bindings: [], 
    __knexQueryUid: '31beb080-c89a-43b2-b112-546077330e82', 
    sql: 'select * from (select 1)' } 
+0

我已经使用了第一种解决方案,'as('t1')'就像一个魅力一样工作。谢谢。 – GilZ

+0

极大地简化了我的代码。非常感谢你。你是一个救星! –

0

丑陋(但工作)解决方案,我发现用knex.rawsubQuery.toString

const query = knex.queryBuilder() 
    .select('*') 
    .from(knex.raw(`(${subQuery})`); 

我不相信这是最好的答案,而且我敢肯定,我失去了一些东西,所以我不接受这个答案呢。

+0

你不应该使用'.toString()'来传递原始查询......这会导致knex插入eg参数绑定本身,它将无法使用数据库驱动程序的实现来防止SQL注入。 '.toSQL()'分别给你绑定和sql。 –