SQL: IF-clausule binnen WHERE-clausule

Is het mogelijk om een IFclausule te gebruiken binnen een WHEREclausule in MS SQL?

Voorbeeld:

WHERE
    IF IsNumeric(@OrderNumber) = 1
        OrderNumber = @OrderNumber
    ELSE
        OrderNumber LIKE '%' + @OrderNumber + '%'

Antwoord 1, autoriteit 100%

Gebruik een CASE-instructie
UPDATE:de vorige syntaxis (zoals aangegeven door een paar mensen) werkt niet. U kunt CASE als volgt gebruiken:

WHERE OrderNumber LIKE
  CASE WHEN IsNumeric(@OrderNumber) = 1 THEN 
    @OrderNumber 
  ELSE
    '%' + @OrderNumber
  END

Of je kunt een IF-statement gebruiken zoals @N. J. Reedwijst erop.


Antwoord 2, autoriteit 64%

Je zou dit moeten kunnen doen zonder IF of CASE

WHERE 
   (IsNumeric(@OrderNumber) AND
      (CAST OrderNumber AS VARCHAR) = (CAST @OrderNumber AS VARCHAR)
 OR
   (NOT IsNumeric(@OrderNumber) AND
       OrderNumber LIKE ('%' + @OrderNumber))

Afhankelijk van de smaak van SQL moet u wellicht de casts op het ordernummer aanpassen naar een INT of VARCHAR, afhankelijk van of impliciete casts worden ondersteund.

Dit is een veel voorkomende techniek in een WHERE-clausule. Als je wat “IF”-logica in de WHERE-component wilt toepassen, hoef je alleen maar de extra voorwaarde met een boolean AND toe te voegen aan de sectie waar deze moet worden toegepast.


Antwoord 3, autoriteit 15%

Je hebt helemaal geen IF-verklaring nodig.

WHERE
    (IsNumeric(@OrderNumber) = 1 AND OrderNumber = @OrderNumber)
OR (IsNumeric(@OrderNumber) = 0 AND OrderNumber LIKE '%' + @OrderNumber + '%')

Antwoord 4, autoriteit 6%

Er is geen goede manier om dit in SQL te doen. Enkele benaderingen die ik heb gezien:

1) Gebruik CASE in combinatie met booleaanse operatoren:

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) Gebruik IF’s buiten 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) Gebruik een lange tekenreeks, stel uw SQL-instructie voorwaardelijk op en gebruik vervolgens EXEC

De derde benadering is afschuwelijk, maar het is bijna de enige die werkt als je een aantal van dergelijke variabele voorwaarden hebt.


Antwoord 5, autoriteit 3%

Gebruik een CASE-instructie in plaats van IF.


Antwoord 6, autoriteit 2%

U wilt de CASE-instructie

WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber)=1 THEN @OrderNumber ELSE '%' + @OrderNumber END

Antwoord 7

Ik denk dat waar…like/=…case…then… kan werken met Booleans. Ik gebruik T-SQL.

Scenario: Laten we zeggen dat je de hobby’s van Person-30 wilt krijgen als Bool onjuist is, en de hobby’s van Person-42 als Bool waar is. (Volgens sommige omvatten hobby-lookups meer dan 90% van de zakelijke berekeningscycli, dus betaal de nauwe attn.).

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;

Antwoord 8

Waar (Isnumeric (@ordernummer) & LT; & GT; 1 of Ordernummer = @ oordorumnummer)
       En (Isnumber (@ordernummer) = 1 of bestelnummer als '%'
                       + @Ordernummer + '%')

Antwoord 9

Case Verklaring is een betere optie dan indien altijd.

 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 

Antwoord 10

   WHERE OrderNumber LIKE CASE WHEN IsNumeric(@OrderNumber) = 1 THEN @OrderNumber ELSE  '%' + @OrderNumber END

In lijngeval staat correct.


Antwoord 11

In SQL Server had ik hetzelfde probleem dat ik alleen een en-verklaring wilde gebruiken als parameter onjuist is en op true moest ik beide waarden tonen als false, dus ik gebruikte het op deze manier

(T.IsPublic = @ShowPublic or  @ShowPublic = 1)

Antwoord 12

Het volgende voorbeeld voert een query uit als onderdeel van de Booleaanse uitdrukking en voert vervolgens iets verschillende statementblokken uit op basis van het resultaat van de Booleaanse uitdrukking. Elk statementblok begint met begin en voltooit met het einde.

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

GEBRUIK GEBRUIKT ALS … ANDERS VERKLARINGEN
Het volgende voorbeeld laat zien hoe een … anders-instructie in een andere kan worden genest. Stel de @nummer variabele in op 5, 50 en 500 om elke instructie te testen.

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

Antwoord 13

// Een voorbeeld voor het gebruik van een opgeslagen procedure om gebruikers gefilterd per land en site te selecteren

CREATE STORED PROCEDURE GetUsers
@CountryId int = null,
@SiteId int = null
AS
BEGIN
SELECT *
        FROM users 
        WHERE
                CountryId  = CASE WHEN ISNUMERIC(@CountryId) = 1 THEN @CountryId ELSE CountryId END AND
                SiteId     = CASE WHEN ISNUMERIC(@SiteId) = 1 THEN @SiteId ELSE SiteId END;

END


Antwoord 14

Om enkele van de logische equivalentieoplossingen te verduidelijken.

Een if-statement

if (a) then b

is logisch equivalent aan

(!a || b)

Het is de eerste regel in de sectie Logische equivalenties met voorwaardelijke uitsprakenvan de Wikipedia-artikel over logische equivalentie.

Als u de elsewilt opnemen, hoeft u alleen nog een voorwaarde toe te voegen

if(a) then b; 
if(!a) then c;

wat logisch equivalent is aan
(!a || b) && (a || c)

Dus gebruik de OP als voorbeeld:

IF IsNumeric(@OrderNumber) = 1
    OrderNumber = @OrderNumber
ELSE
    OrderNumber LIKE '%' + @OrderNumber + '%'

het logische equivalent zou zijn:

(IsNumeric(@OrderNumber) <> 1 OR OrderNumber = @OrderNumber)
AND (IsNumeric(@OrderNumber) = 1 OR OrderNumber LIKE '%' + @OrderNumber + '%' )

Antwoord 15

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 

Zie of dit helpt.


Antwoord 16

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

Other episodes