Подтвердить что ты не робот

Условное предложение 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?

4b9b3361

Ответ 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