sql >> Databasteknik >  >> RDS >> Sqlserver

SQL Case uttalande inom SQL IN

Du kan göra det med en OR :

WHERE   (@Id > 0 AND Table1.Field = @Id)
OR      (@Id = 0 AND Table1.Field IN (6,16,18))

Jag skulle dock råda dig att använda (som du har sagt) IF/ELSE , när man blandar ihop två tillstånd som detta kan man ofta tvinga fram suboptimala planer. t.ex. i ditt exempel kan du förenkla detta till ett schema enligt följande:

CREATE TABLE T
(   ID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY, 
    Field INT NOT NULL, 
    SomeOtherField INT NULL
);
GO
INSERT T  (Field)
SELECT  Number
FROM    Master..spt_values
        CROSS JOIN (VALUES (1), (2), (3)) t (A)
WHERE   Type = 'P'
GO
CREATE NONCLUSTERED INDEX IX_T_Field ON T (Field) INCLUDE (SomeOtherField);

Detta fyller helt enkelt en av kolumnerna med siffrorna 0-2047 upprepade 4 gånger vardera (bara för några exempeldata). Sedan Om jag skapar två procedurer, en som använder 'OM/ELSE' en som kombinerar kriterierna enligt ovan:

CREATE PROCEDURE dbo.Test @ID INT
AS
    SELECT  ID, Field, SomeOtherField
    FROM    T
    WHERE   (@Id > 0 AND T.Field = @Id)
    OR      (@Id = 0 AND T.Field IN (6,16,18))

GO
CREATE PROCEDURE dbo.Test2 @ID INT
AS
    IF @ID = 0
        SELECT  ID, Field, SomeOtherField
        FROM    T
        WHERE   T.Field IN (6, 16, 18)
    ELSE
        SELECT  ID, Field, SomeOtherField
        FROM    T
        WHERE   T.Field = @Id
GO

Eftersom sammanställning av frågor bara sker en gång (om du inte uttryckligen säger något annat), kommer optimeraren inte att välja en annan plan beroende på om du skickar 0 eller skickar ett ID> 0 till proceduren, så båda av följande:

EXECUTE dbo.Test 0;
EXECUTE dbo.Test 1;

Kommer att ge denna plan:

Den andra proceduren kan uppskatta den bästa utförandeplanen mycket bättre så kör den här:

EXECUTE dbo.Test2 0;
EXECUTE dbo.Test2 1;

Ger följande plan:

Exemplen i den verkliga världen kommer uppenbarligen att variera, och jag har medvetet konstruerat ett exempel som bevisar min poäng. Det är lite mer ansträngning att duplicera mycket kod genom att använda IF/ELSE , men det är ofta värt det.



  1. mysql-uppdateringsfråga med inre join

  2. Pyodbc:Inloggningstidsgränsfel

  3. Installerar python-mysql med wamps mysql

  4. Mysql radera i en tabell med id från en annan tabell