[英]Is there a command which combines the functionalities of UNION and JOIN in 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.