¿Es posible usar una cláusula IF dentro de una cláusula WHERE en MS SQL?
Ejemplo:
WHERE
IF IsNumeric(@OrderNumber) = 1
OrderNumber = @OrderNumber
ELSE
OrderNumber LIKE '%' + @OrderNumber + '%'
¿Es posible usar una cláusula IF dentro de una cláusula WHERE en MS SQL?
Ejemplo:
WHERE
IF IsNumeric(@OrderNumber) = 1
OrderNumber = @OrderNumber
ELSE
OrderNumber LIKE '%' + @OrderNumber + '%'
Respuestas:
Utilice una instrucción CASE
ACTUALIZACIÓN: la sintaxis anterior (como lo señalaron algunas personas) no funciona. Puede usar CASE de la siguiente manera:
WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber) = 1 THEN
@OrderNumber
ELSE
'%' + @OrderNumber
END
O puede usar una declaración IF como @ NJ Reed señala.
CASE
es la solución adecuada en la mayoría de los casos. En mi caso, quería cambiar el operador de comparación y, por lo tanto, utilicé el siguiente enfoque.
Debería poder hacer esto sin IF o CASE
WHERE
(IsNumeric(@OrderNumber) AND
(CAST OrderNumber AS VARCHAR) = (CAST @OrderNumber AS VARCHAR)
OR
(NOT IsNumeric(@OrderNumber) AND
OrderNumber LIKE ('%' + @OrderNumber))
Dependiendo del sabor de SQL, es posible que necesite ajustar los conversiones en el número de pedido a un INT o VARCHAR dependiendo de si se admiten conversiones implícitas.
Esta es una técnica muy común en una cláusula WHERE. Si desea aplicar alguna lógica "IF" en la cláusula WHERE, todo lo que necesita hacer es agregar la condición adicional con un booleano AND a la sección donde debe aplicarse.
No necesita una declaración IF en absoluto.
WHERE
(IsNumeric(@OrderNumber) = 1 AND OrderNumber = @OrderNumber)
OR (IsNumeric(@OrderNumber) = 0 AND OrderNumber LIKE '%' + @OrderNumber + '%')
where (@AdmUserId is null or CurrentOrder.CustomerAdmUserId = @AdmUserId)
o solo filtra si IncludeDeleted = 0: where (@IncludeDeleted = 1 or ItemObject.DeletedFlag = 0)
No hay una buena manera de hacer esto en SQL. Algunos enfoques que he visto:
1) Use CASE combinado con operadores booleanos:
WHERE
OrderNumber = CASE
WHEN (IsNumeric(@OrderNumber) = 1)
THEN CONVERT(INT, @OrderNumber)
ELSE -9999 -- Some numeric value that just cannot exist in the column
END
OR
FirstName LIKE CASE
WHEN (IsNumeric(@OrderNumber) = 0)
THEN '%' + @OrderNumber
ELSE ''
END
2) Use IF fuera de SELECT
IF (IsNumeric(@OrderNumber)) = 1
BEGIN
SELECT * FROM Table
WHERE @OrderNumber = OrderNumber
END ELSE BEGIN
SELECT * FROM Table
WHERE OrderNumber LIKE '%' + @OrderNumber
END
3) Usando una cadena larga, componga su declaración SQL condicionalmente, y luego use EXEC
El tercer enfoque es horrible, pero es casi el único que funciona si tiene una serie de condiciones variables como esa.
IF...ELSE...
condicionales en booleano AND
's y OR
' s como en @ njr101 respuesta anterior. La desventaja de ^ este enfoque es que puede ser muy difícil si tienes muchos IF
, o si tienes muchos anidados
Use una declaración CASE en lugar de IF.
Desea la declaración CASE
WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber)=1 THEN @OrderNumber ELSE '%' + @OrderNumber END
Creo que donde ... como / = ... case ... entonces ... puede funcionar con Booleans. Estoy usando T-SQL.
Escenario: Digamos que desea obtener los pasatiempos de la Persona-30 si bool es falso y los pasatiempos de la Persona-42 si bool es verdadero. (Según algunos, las búsquedas de pasatiempos comprenden más del 90% de los ciclos de cómputo de negocios, por lo tanto, pague cerca).
CREATE PROCEDURE sp_Case
@bool bit
AS
SELECT Person.Hobbies
FROM Person
WHERE Person.ID =
case @bool
when 0
then 30
when 1
then 42
end;
WHERE (IsNumeric (@OrderNumber) <> 1 OR OrderNumber = @OrderNumber) AND (IsNumber (@OrderNumber) = 1 OR OrderNumber LIKE '%' + @OrderNumber + '%')
IF P THEN Q ELSE R
<=>
( ( NOT P ) OR Q ) AND ( P OR R )
La declaración CASE es una mejor opción que SI siempre.
WHERE vfl.CreatedDate >= CASE WHEN @FromDate IS NULL THEN vfl.CreatedDate ELSE @FromDate END
AND vfl.CreatedDate<=CASE WHEN @ToDate IS NULL THEN vfl.CreatedDate ELSE @ToDate END
WHERE OrderNumber LIKE CASE WHEN IsNumeric(@OrderNumber) = 1 THEN @OrderNumber ELSE '%' + @OrderNumber END
En línea caso Condición funcionará correctamente.
El siguiente ejemplo ejecuta una consulta como parte de la expresión booleana y luego ejecuta bloques de sentencias ligeramente diferentes en función del resultado de la expresión booleana. Cada bloque de instrucciones comienza con BEGIN y termina con END.
USE AdventureWorks2012;
GO
DECLARE @AvgWeight decimal(8,2), @BikeCount int
IF
(SELECT COUNT(*) FROM Production.Product WHERE Name LIKE 'Touring-3000%' ) > 5
BEGIN
SET @BikeCount =
(SELECT COUNT(*)
FROM Production.Product
WHERE Name LIKE 'Touring-3000%');
SET @AvgWeight =
(SELECT AVG(Weight)
FROM Production.Product
WHERE Name LIKE 'Touring-3000%');
PRINT 'There are ' + CAST(@BikeCount AS varchar(3)) + ' Touring-3000 bikes.'
PRINT 'The average weight of the top 5 Touring-3000 bikes is ' + CAST(@AvgWeight AS varchar(8)) + '.';
END
ELSE
BEGIN
SET @AvgWeight =
(SELECT AVG(Weight)
FROM Production.Product
WHERE Name LIKE 'Touring-3000%' );
PRINT 'Average weight of the Touring-3000 bikes is ' + CAST(@AvgWeight AS varchar(8)) + '.' ;
END ;
GO
Uso de instrucciones anidadas IF ... ELSE El siguiente ejemplo muestra cómo una declaración IF ... ELSE puede anidarse dentro de otra. Establezca la variable @Number en 5, 50 y 500 para probar cada instrucción.
DECLARE @Number int
SET @Number = 50
IF @Number > 100
PRINT 'The number is large.'
ELSE
BEGIN
IF @Number < 10
PRINT 'The number is small'
ELSE
PRINT 'The number is medium'
END ;
GO
En el servidor sql tuve el mismo problema, quería usar una instrucción y solo si el parámetro es falso y en verdadero tuve que mostrar los valores verdadero y falso, así que lo usé de esta manera
(T.IsPublic = @ShowPublic or @ShowPublic = 1)
If @LstTransDt is Null
begin
Set @OpenQty=0
end
else
begin
Select @OpenQty=IsNull(Sum(ClosingQty),0)
From ProductAndDepotWiseMonitoring
Where Pcd=@PCd And PtpCd=@PTpCd And TransDt=@LstTransDt
end
A ver si esto ayuda.
USE AdventureWorks2012;
GO
IF
(SELECT COUNT(*) FROM Production.Product WHERE Name LIKE 'Touring-3000%' ) > 5
PRINT 'There are more than 5 Touring-3000 bicycles.'
ELSE PRINT 'There are 5 or less Touring-3000 bicycles.' ;
GO