簡體   English   中英

如何在 MikroORM 中運行 `union` SQL 命令

[英]How to run `union` SQL command in MikroORM

還詢問了GitHub


我想在 MikroORM 中使用union 似乎沒有內置方式(如qb.union() ,因此我認為我需要運行原始 SQL 命令(通過qb.raw() )或使用 Knex 構建命令。

例如,我想根據某些條件從表中獲取一些行,但是無論如何,至少要返回具有最大 ID 的兩行。

(
  select * from sch.tbl
  -- where  -- insert some condition, e.g. `id > 10`
  order by id desc
) union (
  select * from sch.tbl order by id desc limit 2
) order by id asc;

我認為這可以通過 Knex 完成,如下所示:

this.orm.em.getKnex()
  .union(qb => qb
    .select('*')
    .withSchema('sch')
    .from('tbl')
    .where('id', '>', 10)
    .orderBy('id', 'DESC')
    .limit(10)
  )
  .union(qb => qb
    .select('*')
    .withSchema('sch')
    .from('tbl')
    .orderBy('id', 'DESC')
    .limit(2)
  )
  .orderBy('id', 'ASC')

但是,我不知道如何得到結果。

當我運行以下命令時:

qb.raw('(select * from ?.? where id > ? order by id desc limit 10) union (select * from ?.? order by id desc limit 2) order by id asc', ['sch', 'tbl', 10, 'sch', 'tbl'])

它構建了一個查詢( qb.getQuery()的輸出) select "s0".* from "sch"."tbl" as "s0" ,這不是我想要的。

謝謝你的幫助!

更新

但是,當我使用? 占位符,它會失敗,因為它用$1替換它們( 1遞增)。 但是,它可以像預期的那樣在沒有占位符的情況下工作。

const knex = this.orm.em.getKnex()

// This fails
const result = await knex.raw('(select * from ?.? where id > ? order by id desc limit 10) union (select * from ?.? order by id desc limit 2) order by id asc', ['sch', 'tbl', 10, 'sch', 'tbl'])

// Error
error: (select * from $1.$2 where id > $3 order by id desc limit 10) union (select * from $4.$5 order by id desc limit 2) order by id asc - syntax error at or near "$1"

// This works
const x = await knex.raw('(select * from sch.tbl where id > 10 order by id desc limit 10) union (select * from sch.tbl order by id desc limit 2) order by id asc', ['sch', 'tbl', 10, 'sch', 'tbl'])

雖然我更喜歡一些語法糖命令(在 MikroORM 或 Knex 中),但原始 SQL 命令是一個很好的解決方法,但是,我想使用占位符(綁定)。 我怎樣才能做到這一點?


更新 2

好吧,我錯過了 Knex 文檔中的那個注釋? 被解釋為值和?? 作為標識符。

此外,我找到了一個使用 Knex 的解決方案(盡管我使用的是 MikroORM):

const knex = this.orm.em.getKnex()

const xKnexRaw = knex
  .withSchema('sch')
  .select('*')
  .from('tbl')
  .where('id', '>', 10)
  .orderBy('start_time', 'desc')
  .limit(10)
  .union(
    qb => qb
      .select('*')
      .withSchema('sch')
      .from('tbl')
      .orderBy('id', 'desc')
      .limit(2),
    true
  )
  .orderBy('start_time', 'asc')

// `res` is a result (array of row) without TypeScript types
const res = await this.orm.em.getConnection().execute(query)
// `entities` is a result (array of entities) with mapped TypeScript types
const entities = res.map(e => this.orm.em.map(StatusInterval, e))

這是一個使用 Knex 的解決方案(盡管我使用的是 MikroORM):

const knex = this.orm.em.getKnex()

const query = knex
  .withSchema('sch')
  .select('*')
  .from('tbl')
  .where('id', '>', 10)
  .orderBy('start_time', 'desc')
  .limit(10)
  .union(
    qb => qb
      .select('*')
      .withSchema('sch')
      .from('tbl')
      .orderBy('id', 'desc')
      .limit(2),
    true
  )
  .orderBy('start_time', 'asc')

// `res` is a result (array of row) without TypeScript types
const res = await this.orm.em.getConnection().execute(query)
// `entities` is a result (array of entities) with mapped TypeScript types
const entities = res.map(e => this.orm.em.map(StatusInterval, e))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM