È possibile utilizzare una clausola IF all'interno di una clausola WHERE in MS SQL?
Esempio:
WHERE
IF IsNumeric(@OrderNumber) = 1
OrderNumber = @OrderNumber
ELSE
OrderNumber LIKE '%' + @OrderNumber + '%'
È possibile utilizzare una clausola IF all'interno di una clausola WHERE in MS SQL?
Esempio:
WHERE
IF IsNumeric(@OrderNumber) = 1
OrderNumber = @OrderNumber
ELSE
OrderNumber LIKE '%' + @OrderNumber + '%'
Risposte:
Utilizzare un'istruzione CASE
AGGIORNAMENTO: la sintassi precedente (come sottolineato da alcune persone) non funziona. Puoi usare CASE come segue:
WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber) = 1 THEN
@OrderNumber
ELSE
'%' + @OrderNumber
END
Oppure puoi usare un'istruzione IF come sottolinea @ NJ Reed .
CASE
è la soluzione appropriata nella maggior parte dei casi. Nel mio caso, volevo cambiare operatore di confronto e quindi ho usato l'approccio successivo.
Dovresti essere in grado di farlo senza IF o CASE
WHERE
(IsNumeric(@OrderNumber) AND
(CAST OrderNumber AS VARCHAR) = (CAST @OrderNumber AS VARCHAR)
OR
(NOT IsNumeric(@OrderNumber) AND
OrderNumber LIKE ('%' + @OrderNumber))
A seconda del tipo di SQL, potrebbe essere necessario modificare i cast sul numero di ordine su INT o VARCHAR a seconda che siano supportati cast impliciti.
Questa è una tecnica molto comune in una clausola WHERE. Se si desidera applicare una logica "IF" nella clausola WHERE, è sufficiente aggiungere la condizione aggiuntiva con un valore booleano AND alla sezione in cui deve essere applicata.
Non hai assolutamente bisogno di un'istruzione IF.
WHERE
(IsNumeric(@OrderNumber) = 1 AND OrderNumber = @OrderNumber)
OR (IsNumeric(@OrderNumber) = 0 AND OrderNumber LIKE '%' + @OrderNumber + '%')
where (@AdmUserId is null or CurrentOrder.CustomerAdmUserId = @AdmUserId)
O filtra solo se IncludeDeleted = 0: where (@IncludeDeleted = 1 or ItemObject.DeletedFlag = 0)
Non c'è un buon modo per farlo in SQL. Alcuni approcci che ho visto:
1) Usa CASE combinato con operatori booleani:
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) Utilizzare gli IF all'esterno di SELECT
IF (IsNumeric(@OrderNumber)) = 1
BEGIN
SELECT * FROM Table
WHERE @OrderNumber = OrderNumber
END ELSE BEGIN
SELECT * FROM Table
WHERE OrderNumber LIKE '%' + @OrderNumber
END
3) Utilizzando una stringa lunga, componi l'istruzione SQL in modo condizionale, quindi utilizza EXEC
Il terzo approccio è orribile, ma è quasi l'unico che funzioni se si dispone di una serie di condizioni variabili come questa.
IF...ELSE...
condizionali in booleano AND
's e OR
' s come in @ njr101 risposta di cui sopra. Unico inconveniente di ^ questo approccio è che può essere tremendamente difficile se ne hai molti IF
o se ne hai molti nidificati
Utilizzare un'istruzione CASE anziché IF.
Vuoi l'istruzione CASE
WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber)=1 THEN @OrderNumber ELSE '%' + @OrderNumber END
Penso che dove ... come / = ... il caso ... allora ... possa funzionare con i booleani. Sto usando T-SQL.
Scenario: supponiamo che tu voglia ottenere gli hobby di Person-30 se il bool è falso, e gli hobby di Person-42 se il bool è vero. (Secondo alcuni, le ricerche di hobby comprendono oltre il 90% dei cicli di calcolo aziendale, quindi paga attentamente).
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 COME '%' + @OrderNumber + '%')
IF P THEN Q ELSE R
<=>
( ( NOT P ) OR Q ) AND ( P OR R )
L' istruzione CASE è l'opzione migliore rispetto a IF sempre.
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
In linea caso Condizione funzionerà correttamente.
L'esempio seguente esegue una query come parte dell'espressione booleana e quindi esegue blocchi di istruzioni leggermente diversi in base al risultato dell'espressione booleana. Ogni blocco di istruzioni inizia con BEGIN e 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 delle istruzioni IF ... ELSE nidificate L'esempio seguente mostra come un'istruzione IF ... ELSE può essere nidificata all'interno di un'altra. Impostare la variabile @Number su 5, 50 e 500 per testare ciascuna istruzione.
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
Nel server sql ho avuto lo stesso problema, volevo usare un'istruzione and solo se il parametro è falso e su true ho dovuto mostrare sia i valori vero che falso, quindi l'ho usato in questo modo
(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
Vedi se questo aiuta.
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