Czy możliwe jest użycie klauzuli IF w klauzuli WHERE w MS SQL?
Przykład:
WHERE
IF IsNumeric(@OrderNumber) = 1
OrderNumber = @OrderNumber
ELSE
OrderNumber LIKE '%' + @OrderNumber + '%'
Czy możliwe jest użycie klauzuli IF w klauzuli WHERE w MS SQL?
Przykład:
WHERE
IF IsNumeric(@OrderNumber) = 1
OrderNumber = @OrderNumber
ELSE
OrderNumber LIKE '%' + @OrderNumber + '%'
Odpowiedzi:
Użyj instrukcji CASE
UPDATE: Poprzednia składnia (jak wskazało kilka osób) nie działa. Możesz użyć CASE w następujący sposób:
WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber) = 1 THEN
@OrderNumber
ELSE
'%' + @OrderNumber
END
Lub możesz użyć wyrażenia IF, takiego jak wskazuje @ NJ Reed .
CASE
jest właściwym rozwiązaniem w większości przypadków. W moim przypadku chciałem zmienić operator porównania i dlatego zastosowałem następne podejście.
Powinieneś być w stanie to zrobić bez IF ani CASE
WHERE
(IsNumeric(@OrderNumber) AND
(CAST OrderNumber AS VARCHAR) = (CAST @OrderNumber AS VARCHAR)
OR
(NOT IsNumeric(@OrderNumber) AND
OrderNumber LIKE ('%' + @OrderNumber))
W zależności od smaku SQL może być konieczne dostosowanie rzutowań numeru zamówienia do INT lub VARCHAR w zależności od tego, czy obsługiwane są rzutowania niejawne.
Jest to bardzo popularna technika w klauzuli WHERE. Jeśli chcesz zastosować logikę „JEŻELI” w klauzuli WHERE, wszystko, co musisz zrobić, to dodać dodatkowy warunek z logiczną wartością logiczną ORAZ do sekcji, w której należy go zastosować.
W ogóle nie potrzebujesz instrukcji IF.
WHERE
(IsNumeric(@OrderNumber) = 1 AND OrderNumber = @OrderNumber)
OR (IsNumeric(@OrderNumber) = 0 AND OrderNumber LIKE '%' + @OrderNumber + '%')
where (@AdmUserId is null or CurrentOrder.CustomerAdmUserId = @AdmUserId)
Lub filtruj tylko, jeśli IncludeDeleted = 0: where (@IncludeDeleted = 1 or ItemObject.DeletedFlag = 0)
Nie ma dobrego sposobu na zrobienie tego w SQL. Niektóre podejścia, które widziałem:
1) Użyj CASE w połączeniu z operatorami logicznymi:
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) Użyj JEŻELI poza WYBOREM
IF (IsNumeric(@OrderNumber)) = 1
BEGIN
SELECT * FROM Table
WHERE @OrderNumber = OrderNumber
END ELSE BEGIN
SELECT * FROM Table
WHERE OrderNumber LIKE '%' + @OrderNumber
END
3) Używając długiego łańcucha, ułóż warunkowo instrukcję SQL, a następnie użyj EXEC
Trzecie podejście jest ohydne, ale jest to prawie jedyna myśl, która działa, jeśli masz wiele takich zmiennych warunków.
IF...ELSE...
warunkowych w logiczne AND
i logiczne , OR
jak w powyższej odpowiedzi @ njr101. Wadą tego podejścia jest to, że może być niezwykle trudne, jeśli masz wiele IF
lub wiele z nich jest zagnieżdżonych
Użyj instrukcji CASE zamiast IF.
Chcesz instrukcji CASE
WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber)=1 THEN @OrderNumber ELSE '%' + @OrderNumber END
Myślę, że gdzie ... jak / = ... przypadek ... to ... może współpracować z Booleanami. Używam T-SQL.
Scenariusz: Powiedzmy, że chcesz zdobyć hobby Osoby-30, jeśli bool jest fałszywy, i hobby Osoby-42, jeśli bool jest prawdziwy. (Według niektórych wyszukiwanie hobbystyczne obejmuje ponad 90% cykli obliczeniowych w biznesie, więc zwróć uwagę.)
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;
GDZIE (IsNumeric (@OrderNumber) <> 1 LUB OrderNumber = @OrderNumber) ORAZ (IsNumber (@OrderNumber) = 1 LUB OrderNumber LIKE „%” + @OrderNumber + '%')
IF P THEN Q ELSE R
<=>
( ( NOT P ) OR Q ) AND ( P OR R )
Instrukcja CASE jest lepszą opcją niż JEŚLI zawsze.
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
W przypadku linii Warunek będzie działał poprawnie.
Poniższy przykład wykonuje kwerendę jako część wyrażenia logicznego, a następnie wykonuje nieco inne bloki instrukcji w zależności od wyniku wyrażenia logicznego. Każdy blok instrukcji zaczyna się od BEGIN i kończy się 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
Korzystanie z zagnieżdżonych instrukcji IF ... ELSE Poniższy przykład pokazuje, w jaki sposób można zagnieździć instrukcję IF… ELSE wewnątrz innej instrukcji. Ustaw zmienną @Number na 5, 50 i 500, aby przetestować każdą instrukcję.
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
Na serwerze sql miałem ten sam problem. Chciałem użyć instrukcji i tylko wtedy, gdy parametr ma wartość false, a na true musiałem pokazywać obie wartości true i false, więc użyłem go w ten sposób
(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
Sprawdź, czy to pomoże.
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