【问题标题】:How to create values list with KnexJS如何使用 KnexJS 创建值列表
【发布时间】:2021-07-20 17:35:16
【问题描述】:

我想生成一个用于查询的动态表。为此,我想使用此处记录的 PostgreSQL 值列表功能:https://www.postgresql.org/docs/13/queries-values.html

SQL 看起来像这样:

with my_values (id, "name") as (
    values (1, 'one'), (2, 'two'), (3, 'three')
)
select *
from my_values mv
join some_other_table sot
    on sot.value_id = mv.id

除了在整个查询中使用raw 之外,我在 KnexJS 文档中找不到任何支持生成上述 SQL 的内容,这违背了使用 KnexJS 的意义。

有没有办法在 KnexJS 中为查询的一部分创建值列表?

【问题讨论】:

  • knex 是一个 sql 查询构建器,因此,它不支持像 with 这样的数据库特定语法。
  • @felixmosh 它确实支持with (knexjs.org/#Builder-with)。我要弄清楚的具体事情是价值列表。如果可能的话,如果有办法将部分原始语句添加到更大的构造语句中,我什至可以。

标签: postgresql knex.js


【解决方案1】:

你可以构造查询

with my_values as (
    Select *
    from (values(1, 'one'), (2, 'two'), (3, 'three')) as inner (id, name)
)
select *
from my_values mv
join some_other_table as sot on sot.value_id = mv.id

问题是knex 不支持您编写的列列表定义。 Postgress,支持这个

SELECT * FROM (VALUES (1, 'one'), (2, 'two'), (3, 'three')) AS t (num,letter);

所以,上面的查询可以这样构建:

const vals = [
  { id: 1, name: 'one' },
  { id: 2, name: 'two' },
  { id: 3, name: 'three' },
];

const params = vals.reduce((result, { id, name }) => result.concat(id, name), []);


await db
  .with(
    `my_values`,
    db.raw(
      `Select * from (values ${vals.map(() => `(?, ?)`).join(',')}) as inner (id, name)`,
      params
    )
  )
  .select('*')
  .from('my_values mv')
  .join('some_other_table', 'some_other_table.value_id', 'mv.id');

它会生成

{
  bindings: [ 1, 'one', 2, 'two', 3, 'three' ],
  sql: 'with `my_values` as (Select * from (values (?, ?),(?, ?),(?, ?)) as inner (id, name)) select * from `my_values_mv` inner join `some_other_table` on `some_other_table`.`value_id` = `mv`.`id`'
}

【讨论】:

    猜你喜欢
    • 2021-09-16
    • 2018-02-26
    • 1970-01-01
    • 2018-03-22
    • 2019-12-11
    • 1970-01-01
    • 1970-01-01
    • 2015-04-06
    • 2020-01-29
    相关资源
    最近更新 更多