Как выбрать строки со значением Нет или NULL, когда параметр = «Нет» и строки со значением «Да», когда параметр = «Да» - PullRequest
0 голосов
/ 20 июня 2019

Мне нужно выбрать строки на основе параметра'@HotList '.

Когда' @HotList '=' Да ', мне нужно вытащить все строки, где поле' co.ro_HotList 'содержит значение'Yes' When '@HotList' = 'No' Мне нужно вытащить все строки, где поле 'co.ro_HotList' содержит значение 'No' ИЛИ ​​null

Я могу выбрать строки, в которых значение равно«Да» или «Нет» только на основе параметра, но не может понять, как также выбрать пустые строки, когда параметр «Нет».Как я могу изменить предоставленный код для достижения этого?

Я пытался использовать оператор case в предложении where, но безуспешно.

SELECT ds.*                     
FROM Rotex_DailyShipmentNotShip ds
left outer join CRM_MSCRM..SalesOrder co ON ds.SOP#=co.Name 
WHERE co.ro_HotList = @HotList

Ответы [ 4 ]

1 голос
/ 20 июня 2019

Попробуйте это где:

ISNULL(co.ro_HotList,'No') = @HotList

ISNULL оценивает нулевое значение для 2-го входа, поэтому все пустые значения рассматриваются как «Нет» в вашем случае.

0 голосов
/ 20 июня 2019

Несколько ответов на вопрос OP верны, потому что они возвращают ожидаемые результаты, но большинство из них неэффективны, потому что они препятствуют правильному использованию индекса.

Заключение имен столбцов в выражения, такие как выражения падежа или функции, предотвращает SQLСервер использует индексы.

Предикаты с оператором OR и условия параметров также препятствуют эффективному плану выполнения.

Существует несколько способов эффективного построения запроса:

Добавить вычисляемый столбец

Добавить вычисляемый столбец, например:

ALTER TABLE ADD HotList AS ISNULL (ro_HotList, 'No')

И индексЭто.Тогда запрос будет проще и удобнее индексировать:

WHERE HotList = @ HotList

Приложение Smart Client

Клиентское приложение может быть достаточно умным, чтобывыполните следующее (псевдокод)

If HostListParameter is "No" then execute the query:
   SELECT <column list>
   FROM Whatever
   WHERE ro_HostList = 'No' OR ro_HostList IS NULL
Else execute this other query:
   SELECT <column list>
   FROM Whatever
   WHERE ro_HostList = @HotList
  Invalid parameter

Использование пакета T-SQL с логикой

Вместо выполнения одного оператора выбора, выполните пакет с логикой

IF @HostList = 'No'
BEGIN
   SELECT <column list>
   FROM Whatever
   WHERE ro_HostList = 'No' OR ro_HostList IS NULL 
END
ELSE
BEGIN
   SELECT <column list>
   FROM Whatever
   WHERE ro_HostList = @HotList
END

Использование хранимой процедуры

Вы можете создать хранимую процедуру, которая выполняет ту же логику, что и предыдущий пакет T-SQL

ИспользованиеOPTION(RECOMPILE)

Добавление OPTION (RECOMPILE)

Добавление OPTION (RECOMPILE) к ответу Impaler приводит к улучшению планов выполнения, которые могут использовать индексы, однако это также предотвращает повторное использование плана.

Но редко используемые индексы с низкой селективностью используются

Если столбец содержит несколько значений, индекс без покрытия в большинстве случаев бесполезен.

В этом случае Iдумаю, что столбец может содержать только «Да», «Нет» или NULL.Так что индексирование не улучшит производительность.И лучший ответ - ответ KeithL.

0 голосов
/ 20 июня 2019

Вы можете написать условие фильтрации, как показано ниже:

SELECT ds.*                     
FROM Rotex_DailyShipmentNotShip ds
left outer join CRM_MSCRM..SalesOrder co ON ds.SOP#=co.Name 
WHERE @HotList = 'Yes' and co.ro_HotList = 'Yes'
   OR @HotList = 'No' and (co.ro_HotList = 'No' or co.ro_HotList is null)
0 голосов
/ 20 июня 2019

Ответ Кейта правильный, но для полноты вы упомянули, что вы пытаетесь CASE, и вот как это следует сделать, используя CASE.

  WHERE CASE WHEN co.ro_HotList IS NULL 
             THEN 'No'
             ELSE co.ro_HotList
        END  = @HotList
...