Поиск нулевых значений с помощью .whereIn - PullRequest
3 голосов
/ 15 октября 2019

Я построил запрос с помощью Knex следующим образом:

knex('discounts')
  .where((builder) => {
    builder
      .where('product_code', productCode)
      .where((builder1) => {
        builder1
          .andWhere('account_code', customer)
          .orWhere('account_code', null);
      });
  })
.select('*');

Все работает нормально, но я чувствовал, что оператор .where слишком длинный, поэтому попытался использовать функцию .whereIn, ивот тогда я понял, что это не работает:

knex('discounts')
  .where((builder) => {
    builder
      .where('product_code', productCode)
      .whereIn('account_code', [customer, null]);
  })
.select('*');

Я знаю, что мы не можем использовать null с IN в сыром SQL, и это должно быть сделано так:

WHERE 
(columnName IN ('value1', 'value2', 'value3') OR columnName IS NULL)

Мой вопрос: мой первоначальный запрос - единственный способ достичь этого или есть какой-нибудь альтернативный способ использования .whereIn с null при использовании Knex?

Ответы [ 2 ]

1 голос
/ 15 октября 2019

Вы правы насчет первого запроса, дополнительная встроенная функция не нужна. Здесь действительно нужна только одна группировка, если я правильно понимаю ваше требование. Так что это нормально:

db("discounts")
  .where("product_code", productCode)
  .where(qb =>
    qb.where("account_code", customer).orWhereNull("account_code")
  )

Это генерирует следующий SQL:

SELECT * FROM "discounts"
  WHERE "product_code" = ?
  AND ("account_code" = ? OR "account_code" IS NULL)

Вы можете использовать .andWhere, если хотите быть более явным, но это не меняетсгенерированный SQL:

  .where("product_code", productCode)
  .andWhere(qb =>

Кстати (если вы еще не обнаружили) вы можете просмотреть, какой SQL будет выполняться для любой цепочки Knex, добавив к ней .debug(). Это может быть удобно, если вы проводите рефакторинг, или просто любопытно.

1 голос
/ 15 октября 2019

Более оптимизированный, я сделаю

   knex('discounts')
   .where('product_code', productCode)
   .where((builder1) => {
        builder1
          .whereIn('account_code', customer)
          .orWhereNull('account_code');
      });
  })
.then();

Был добавлен встроенный where и .orWhere('account_code', null); был заменен на orWhereNull. Советы, если вы выбираете *, не нужно писать select, по умолчанию выбран построитель запросов. Внутри массива whereIn значениями могут быть одна / несколько переменных с нулевыми значениями, knex не переводит whereIn в => whereIn or where Is NOT NULL

...