【问题标题】:How to combine AND and OR with Knex?如何将 AND 和 OR 与 Knex 结合?
【发布时间】:2021-08-11 02:16:14
【问题描述】:

我无法在 Knex 中创建以下 SQL 查询:

SELECT * FROM tasks WHERE (code = 'export') AND (status = 'failed' OR status = 'complete')

使用代码:

const queryResult = await this.db('tasks')
        .select('*')
        .where(async function () {

          if ('code' in query) {
            this.where('code', query.code)
          }

          if ('status' in query) {
            if (isArray(query.status)) {
              return query.status.map(status => this.orWhere('status', status))
            } else {
              this.andWhere('status', query.status)
            }
          }
        })
        .orderBy('created_at', 'DESC')

当提供多个状态的数组时,它会忽略“code = export”值并选择所有内容。

【问题讨论】:

  • 您不需要orWhere 和循环。只需使用whereIn('status', query.status)
  • 那是因为你正在构建一个像code = 'exports' OR status = 'failed' OR status = 'complete' 这样的查询——想想看,在这个代码路径中没有andWhere,只有orWhere!您需要将ORs 放入.andWhere(function () {}) 调用中以创建AND 和括号,或者更好的是,在数组案例中使用code = 'export' AND status IN ('failed', 'complete')andWhere(status, 'IN', query.status)
  • .where() 回调不是异步的

标签: javascript typescript knex.js


【解决方案1】:

使用modify

const queryResult = await this.db('tasks')
    .select('*')
    .modify(function(queryBuilder) {
      if ('code' in query) {
        queryBuilder.where('code', query.code)
      }
      if ('status' in query) {
        if (isArray(query.status)) {
          query.status.map(status => queryBuilder.orWhere('status', status))
        } else {
          queryBuilder.andWhere('status', query.status)
        }
      }
    })
    .orderBy('created_at', 'DESC')        

【讨论】:

  • 问题仍然是在 OP 描述的情况下构建了一个只有 OR 的查询。需要.andWhere(function...) 来解决。
  • 这个基本情况不需要修改
【解决方案2】:
const query = knex('tasks');

if ('code' in query) {
  query.where('code', query.code);
}

if ('status' in query) {
  query.where(builder => {
    const statuses = isArray(query.status) ? query.status : [query.status];
    for (let status of statuses) {
      builder.orWhere('status', status);
    }
  });
}

const result = await query;

【讨论】:

    猜你喜欢
    • 2012-11-03
    • 2015-02-14
    • 1970-01-01
    • 2017-02-24
    • 2011-09-08
    • 2016-04-13
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    相关资源
    最近更新 更多