sql >> Database teknologi >  >> RDS >> Sqlserver

SQL-sagserklæring i SQL IN

Du kan gøre det ved at bruge en OR :

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

Jeg vil dog anbefale at bruge (som du har sagt) IF/ELSE , når du mæsker to forhold som denne sammen, kan du ofte fremtvinge suboptimale planer. i dit eksempel kan du forenkle dette til et skema som følger:

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);

Dette udfylder simpelthen en af ​​kolonnerne med tallene 0-2047 gentaget 4 gange hver (bare for nogle eksempler på data). Så hvis jeg opretter to procedurer, en der bruger 'IF/ELSE' en der kombinerer kriterierne som ovenfor:

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

Da kompilering af forespørgsler kun vil ske én gang (medmindre du udtrykkeligt siger andet), vil optimeringsværktøjet ikke vælge en anden plan, afhængigt af om du videregiver 0 eller sender et ID> 0 til proceduren, så begge af følgende:

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

Vil give denne plan:

Den anden procedure er i stand til at estimere den bedste udførelsesplan meget bedre, så kør denne:

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

Giver følgende plan:

Eksempler fra den virkelige verden vil naturligvis variere, og jeg har bevidst konstrueret et eksempel, der beviser min pointe. Det er lidt mere besvær at duplikere en masse kode ved at bruge IF/ELSE , men det er ofte det værd.



  1. Hvordan gør man en kolonne unik i SQL?

  2. Deltag i to tabeller baseret på nærliggende tidsstempler

  3. SQL MAX af flere kolonner?

  4. Sådan indstilles timeout i mysql c++ stik