Инструкция Where для исключения записей, но только если другой столбец равен x

#sql #tsql

#sql #tsql

Вопрос:

Я пытаюсь исключить записи из инструкции sql select с наиболее подробным столбцом в моей таблице salesfacts, который является номером счета, но проблема в том, что номер счета мог использоваться в предыдущие годы (я проверил, что в таблице 26 дубликатов). Я знаю, что это проблема бизнес-правила, но у меня нет возможности ее изменить.

Код, из которого я пытаюсь это исключить, является частью длинной инструкции sql с тремя основными частями, которые объединены с инструкциями объединения, тремя частями являются: дебиторская задолженность, открытые заказы и записи журнала. В этом случае я пытаюсь исключить записи из раздела «дебиторская задолженность».

Итак, для этого экземпляра я пытаюсь исключить 5 номеров счетов-фактур из части «дебиторская задолженность», но только если они происходят в марте 2019 года. (таким образом, это гарантирует, что я не исключаю повторяющиеся номера счетов-фактур, которые могут существовать или не существовать в предыдущие периоды). Возможно, я параноик, и, вероятно, все будет в порядке, поскольку вероятность того, что запись, которую я хочу исключить, на самом деле повторяется, невелика, но если бизнес-правила разрешают повторения, я не хочу рисковать непреднамеренными результатами.

Я хотел бы найти простой способ добавить их в простой оператор where вместо использования ‘except’, потому что мне придется исключить другие записи в будущем, и я не знаю, будут ли работать несколько исключений и объединений.

Не работает:

 Select invoicedate,invoiceno
from saleshistory
where (invoiceno != '1001' and invoicedate = '2011-01-14')
  

Выше показаны все записи с invoicedate 2011-01-14, кроме invoiceno 1001. Я хочу, чтобы код отображал все записи, кроме invoiceno 1001, если это произошло в 2011-01-14.

Ответ №1:

Оператор может быть записан следующим образом:

 Select invoicedate,invoiceno
from saleshistory
where (invoiceno <> '1001' or invoicedate <> '2011-01-14')
  

потому что вы хотите отрицать это:

 invoiceno = '1001' and invoicedate = '2011-01-14'
  

итак:

 NOT (invoiceno = '1001' and invoicedate = '2011-01-14')
  

эквивалентно

 invoiceno <> '1001' or invoicedate <> '2011-01-14'
  

Комментарии:

1. Я знал, что есть простой ответ! Спасибо. По-видимому, мне нужно вернуться к моим старым учебникам по логике. Я объединил несколько записей с ‘not in’, и это работает так же

2. Логика, булева алгебра и т.д. Незабываемы.

Ответ №2:

Я не знаю, понимаю ли я вас:

 Select invoicedate,invoiceno
from saleshistory
where (invoiceno != '1001' or ( invoiceno = '1001' and invoicedate = '2011-01-14'))
  

С помощью этого вы можете получить все записи с invoiceno, отличным от 1001, на любую дату, а также записи с invoiceno 1001 и датой 2011-01-14.

Ответ №3:

Я пытаюсь исключить 5 номеров счетов из части дебиторской задолженности, но только если они происходят в марте 2019 года

Следующая реализует эту логику:

 select sh.*
from saleshistory sh
where not (invoiceno in ( . . . ) and  -- list of invoice numbers here
           invoicedate >= '2019-03-01' and
           invoicedate < '2019-04-01'
          );
  

Учитывая описание в тексте, я озадачен, почему у вас есть константа '2011-01-14' в вашем примере запроса.