如何修复由knex中的union构建的查询

时间:2019-08-03 09:44:18

标签: node.js knex.js pg

我正在将knex和pg一起用于从数据库中获取一些数据。 我尝试通过knex构建的查询是:

select "fixtime" from "positions" order by "fixtime" desc limit(1) 
union 
select "fixtime" from "positions" order by "fixtime" limit (1)

但是,当我使用'union'时,knex返回以下查询。当我尝试获得结果时,我得到了错误。

console.log(db.select('fixtime').from('positions').orderBy('fixtime').limit(1).union([db.select('fixtime').from('positions').orderBy('fixtime','desc').limit(1)]).toSQL())

这是控制台的结果:

select "fixtime" from "positions" 
union 
select "fixtime" from "positions" order by "fixtime" desc limit ? order by "fixtime" asc limit ?

db.select('fixtime').from('positions').orderBy('fixtime').limit(1).union([db.select('fixtime').from('positions').orderBy('fixtime','desc').limit(1)]).then(arr => console.log)

这是我得到的错误: 未处理的拒绝错误:“订单”处或附近的语法错误

当我使用单个查询时,我可以获得结果。 如何使用knex修复此查询,或者它是一个错误?

1 个答案:

答案 0 :(得分:0)

我相信Knex无法做到这一点。有一个issue描述了类似的内容。

但是...您可以通过使用两个CTEs

Postgres欺骗结果
const sql = db
  .with('first', qb => {
    qb.select('fixtime')
      .from('tc_positions')
      .orderBy('fixtime', 'asc')
      .limit(1);
  })
  .with('last', qb => {
    qb.select('fixtime')
      .from('tc_positions')
      .orderBy('fixtime', 'desc')
      .limit(1);
  })
  .select('*')
  .from('first')
  .union(function() {
    this.select('*').from('last');
  })
  .toSQL();

console.log(sql);

这将产生:

WITH "first" AS (
    SELECT
        "fixtime"
    FROM
        "tc_positions"
    ORDER BY
        "fixtime" ASC
    LIMIT ?
),
"last" AS (
    SELECT
        "fixtime"
    FROM
        "tc_positions"
    ORDER BY
        "fixtime" DESC
    LIMIT ?
)
SELECT
    *
FROM
    "first"
UNION
SELECT
    *
FROM
    "last"