将原始 SQL 转换为 Bookshelf/Knex

Convert Raw SQL to Bookshelf/Knex

我正在尝试将简单的原始 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);
        })

为了匹配原始查询中的括号,您需要将函数嵌套到您的 kenx 查询中。根据您是想使用 Bookshelf 还是只使用 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);