update - where condition sql server
Cláusula WHERE condicional en SQL Server (4)
Estoy creando una consulta SQL en la que necesito una cláusula where
condicional.
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 está funcionando. ¿No es esta la sintaxis correcta o hay otra forma de hacer esto que no sé?
No quiero usar SQL dinámico, ¿hay alguna otra manera o tengo que usar una solución alternativa como usar if else
y usar la misma consulta con diferentes cláusulas where
?
El problema con su consulta es que en las expresiones CASE
, las partes THEN
y ELSE
deben tener una expresión que evalúe un número o un varchar o 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 volver a escribirla:
WHERE
DateDropped = 0
AND ( @JobsOnHold = 1 AND DateAppr >= 0
OR (@JobsOnHold <> 1 OR @JobsOnHold IS NULL) AND DateAppr <> 0
)
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 debe tener un valor de tipo de datos normal, no un valor booleano. Tiene que ser un varchar, o un int, o algo. Es la misma razón por la que no puede decir SELECT Name, 76 = Age FROM [...]
y espera obtener ''Frank'', FALSE
en el conjunto de resultados.
Además, todas las expresiones en una cláusula WHERE deben tener un valor booleano. No pueden tener un valor de varchar o int. No puedes decir WHERE Name;
o WHERE ''Frank'';
. Debe usar un operador de comparación para que sea una expresión booleana, por lo tanto, 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 solo!
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 a 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 prefieres, también.
Por lo general, puede volver a escribir 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 fácil de usar utilizar una expresión existente que convertir la lógica.
Prueba este -
WHERE DateDropped = 0
AND (
(ISNULL(@JobsOnHold, 0) = 1 AND DateAppr >= 0)
OR
(ISNULL(@JobsOnHold, 0) != 1 AND DateAppr != 0)
)
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)
)