将原始 SQL 转换为 Bookshelf/Knex

Posted

技术标签:

【中文标题】将原始 SQL 转换为 Bookshelf/Knex【英文标题】:Convert Raw SQL to Bookshelf/Knex 【发布时间】:2021-09-14 01:55:14 【问题描述】:

我正在尝试将一个简单的原始 SQL 转换为在 javascript 中使用 Bookshelf/Knex:

原SQL:select * from o where o.id = 1 or o.id = 2 and (o.is_a = true or o.is_b = true) and o.status = 'good';

我尝试使用 .orWhere .andWhere 以多种方式重写它,但无法获得与 SQL 相同的结果。我做错了什么?

一些尝试:

await O.forge()
         .query(
             where: is_a: true,
             orWhere: is_b: true,
         )
         .query('whereIn', 'id', ids)
         .query('whereIn', 'status', goodStatuses)

另一个尝试:

.query(async qb => 
            qb.where('is_a', '=', true)
                .orWhere('is_b', '=', true)
                .andWhere('id', 'in', ids)
                .andWhere('status', 'in', goodStatuses);
        )

【问题讨论】:

【参考方案1】:

为了匹配原始查询中的括号,您需要将函数嵌套到您的 kenx 查询中。根据您是想使用 Bookshelf 还是只使用 knex,这两种方法都应该起作用。

仅限 knex:

await knex('o')
    .where('o.id', 1)
    .orWhere('o.id', 2)
    .andWhere(function() 
        this.where('o.is_a', true)
        .orWhere('o.is_b', true)
    )
    .andWhere('o.status', 'good');

或者您可以使用您的书架模型并将相同的查询传递给查询构建器

await model.query(qb => 
    qb.where('o.id', 1)
    .orWhere('o.id', 2)
    .andWhere(function() 
        this.where('o.is_a', true)
        .orWhere('o.is_b', true)
    )
    .andWhere('o.status', 'good');
).fetch();

或者您似乎已经改进了原始查询以使用 in 而不是多个 ors

await knex('o')
    .where('o.id', 'in', ids)
    .andWhere(function() 
        this.where('o.is_a', true)
        .orWhere('o.is_b', true)
    )
    .andWhere('o.status', 'in', goodStatuses);

【讨论】:

以上是关于将原始 SQL 转换为 Bookshelf/Knex的主要内容,如果未能解决你的问题,请参考以下文章

将原始 SQL 转换为 Laravel 查询构建器

如何将原始 SQL 查询转换为 Silverstripe SQLQuery 抽象层

如何将原始 SQL 转换为 Yii2,如查找查询

将SQL从一列多个原始数据转换为多列

CASE 语句将 NUMBER 转换为 CHAR,但在 Oracle SQL 中保留原始 NUMBER 的 ELSE

转换为 ActiveRecord 查询(火鸟数据库)时导致错误的原始 SQL 查询