Cláusula WHERE condicional en SQL Server


Estoy creando una consulta SQL en la que necesito una cláusula condicional where.

Debería ser algo como esto:

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

La consulta anterior no funciona. ¿No es esta la sintaxis correcta o hay otra manera de hacer esto que no conozco?

No quiero usar SQL dinámico, así que ¿hay alguna otra forma o tengo que usar una solución alternativa como usar if else y usar la misma consulta con diferentes cláusulas where?

Author: numaroth, 2013-09-05

4 answers

Prueba esto

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)
    )

Puedes leer más sobre condicional DONDE aquí.

 61
Author: Coder of Code,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-13 13:05:38

Prueba este-

WHERE DateDropped = 0
    AND (
        (ISNULL(@JobsOnHold, 0) = 1 AND DateAppr >= 0) 
        OR 
        (ISNULL(@JobsOnHold, 0) != 1 AND DateAppr != 0)
    )
 23
Author: Devart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-05 15:50:21

Para responder a la pregunta subyacente de cómo usar una expresión CASE en la cláusula WHERE:

Primero recuerde que el valor de una expresión CASE tiene que tener un valor de tipo de datos normal, no un valor booleano. Tiene que ser un varchar, o un int, o algo así. Es la misma razón por la que no puedes decir SELECT Name, 76 = Age FROM [...] y esperar obtener 'Frank', FALSE en el conjunto de resultados.

Además, todas las expresiones en una cláusula WHERE deben tener un valor booleano. Ellos no pueden tener un valor de varchar o an int. No puedes decir WHERE Name; o WHERE 'Frank';. Tienes que usar un operador de comparación para convertirlo en una expresión booleana, así que WHERE Name = 'Frank';

Eso significa que la expresión CASE debe estar en un lado de una expresión booleana. Tienes que comparar la expresión CASE con algo. ¡No puede sostenerse sola!

Aquí:

WHERE 
    DateDropped = 0
    AND CASE
            WHEN @JobsOnHold  = 1 AND DateAppr >= 0 THEN 'True'
            WHEN DateAppr != 0 THEN 'True'
            ELSE 'False'
        END = 'True'

Observe cómo al final la expresión CASE de la izquierda convertirá la expresión booleana en 'True' = 'True' o 'False' = 'True'.

Tenga en cuenta que no hay nada especial acerca de 'False' y 'True'. Puedes usar 0 y 1 si lo prefieres, también.

Normalmente puede reescribir la expresión CASE en expresiones booleanas con las que estamos más familiarizados, y eso generalmente es mejor para el rendimiento. Sin embargo, a veces es más fácil o más mantenible usar una expresión existente que convertir la lógica.

 9
Author: Bacon Bits,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-25 23:07:35

El problema con su consulta es que en las expresiones CASE, las partes THEN y ELSE deben tener una expresión que se evalúe a un número o a un varchar o a cualquier otro tipo de datos, pero no a un valor booleano.

Solo necesita usar la lógica booleana (o más bien la lógica ternaria que usa SQL) y reescribirla:

WHERE 
    DateDropped = 0
AND ( @JobsOnHold = 1 AND DateAppr >= 0 
   OR (@JobsOnHold <> 1 OR @JobsOnHold IS NULL) AND DateAppr <> 0
    )
 7
Author: ypercubeᵀᴹ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-05 15:50:13