Условное предложение WHERE в SQL Server
Я создаю SQL-запрос, в котором мне требуется условное предложение where
.
Это должно быть примерно так:
SELECT
DateAppr,
TimeAppr,
TAT,
LaserLTR,
Permit,
LtrPrinter,
JobName,
JobNumber,
JobDesc,
ActQty,
(ActQty-LtrPrinted) AS L,
(ActQty-QtyInserted) AS M,
((ActQty-LtrPrinted)-(ActQty-QtyInserted)) AS N
FROM
[test].[dbo].[MM]
WHERE
DateDropped = 0
--This is where i need the conditional clause
AND CASE
WHEN @JobsOnHold = 1 THEN DateAppr >= 0
ELSE DateAppr != 0
END
Вышеуказанный запрос не работает. Разве это не правильный синтаксис или есть другой способ сделать это, что я не знаю?
Я не хочу использовать динамический SQL, так есть ли другой способ или мне нужно использовать обходной путь, например, используя if else
и используя тот же запрос с различными предложениями where
?
Ответы
Ответ 1
Попробуйте это
SELECT
DateAppr,
TimeAppr,
TAT,
LaserLTR,
Permit,
LtrPrinter,
JobName,
JobNumber,
JobDesc,
ActQty,
(ActQty-LtrPrinted) AS L,
(ActQty-QtyInserted) AS M,
((ActQty-LtrPrinted)-(ActQty-QtyInserted)) AS N
FROM
[test].[dbo].[MM]
WHERE
DateDropped = 0
AND (
(ISNULL(@JobsOnHold, 0) = 1 AND DateAppr >= 0)
OR
(ISNULL(@JobsOnHold, 0) != 1 AND DateAppr != 0)
)
Подробнее об условном WHERE читайте здесь.
Ответ 2
Попробуйте этот вариант -
WHERE DateDropped = 0
AND (
(ISNULL(@JobsOnHold, 0) = 1 AND DateAppr >= 0)
OR
(ISNULL(@JobsOnHold, 0) != 1 AND DateAppr != 0)
)
Ответ 3
Чтобы ответить на вопрос о том, как использовать выражение CASE в предложении WHERE:
Сначала помните, что значение выражения CASE должно иметь нормальное значение типа данных, а не логическое значение. Это должен быть varchar, или int, или что-то еще. По той же причине вы не можете сказать SELECT Name, 76 = Age FROM [...]
и ожидаете получить 'Frank', FALSE
в результирующем наборе.
Кроме того, все выражения в предложении WHERE должны иметь логическое значение. Они не могут иметь значение varchar или int. Вы не можете сказать WHERE Name;
или WHERE 'Frank';
. Вы должны использовать оператор сравнения, чтобы сделать его логическим выражением, поэтому WHERE Name = 'Frank';
Это означает, что выражение CASE должно быть на одной стороне булевого выражения. Вы должны сравнить выражение CASE с чем-то. Он не может стоять сам по себе!
Здесь:
WHERE
DateDropped = 0
AND CASE
WHEN @JobsOnHold = 1 AND DateAppr >= 0 THEN 'True'
WHEN DateAppr != 0 THEN 'True'
ELSE 'False'
END = 'True'
Обратите внимание, как в конце выражение CASE слева превратит логическое выражение в 'True' = 'True'
или 'False' = 'True'
.
Обратите внимание, что нет ничего особенного в 'False'
и 'True'
. Вы можете использовать 0
и 1
, если хотите, тоже.
Обычно вы можете переписать выражение CASE в булевы выражения, с которыми мы более знакомы, и что в целом лучше для производительности. Однако иногда проще или легче обслуживать существующее выражение, чем преобразовать логику.
Ответ 4
Проблема с вашим запросом заключается в том, что в выражениях CASE
части THEN
и ELSE
должны иметь выражение, которое вычисляет число или varchar или любой другой тип данных, но не логическое значение.
Вам просто нужно использовать логическую логику (точнее, тернарную логику, используемую SQL) и переписать ее:
WHERE
DateDropped = 0
AND ( @JobsOnHold = 1 AND DateAppr >= 0
OR (@JobsOnHold <> 1 OR @JobsOnHold IS NULL) AND DateAppr <> 0
)
Ответ 5
Часто, когда вы используете условные предложения WHERE, вы заканчиваете upp крайне неэффективным запросом, что заметно для больших наборов данных, где используются индексы. Отличный способ оптимизировать запрос для различных значений вашего параметра - составить отдельный план выполнения для каждого значения параметра. Вы можете достичь этого, используя OPTION (RECOMPILE)
.
В этом примере это, вероятно, не будет иметь большого значения, но, скажем, условие следует использовать только в одном из двух случаев, тогда вы можете заметить большое влияние.
В этом примере:
WHERE
DateDropped = 0
AND (
(ISNULL(@JobsOnHold, 0) = 1 AND DateAppr >= 0)
OR
(ISNULL(@JobsOnHold, 0) <> 1 AND DateAppr <> 0)
)
OPTION (RECOMPILE)
Обнаружение параметров источника , встраивание и параметры RECOMPILE