2017-02-08 89 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。 –