sql >> Databáze >  >> RDS >> Sqlserver

Sql Case prohlášení v SQL IN

Můžete to udělat pomocí OR :

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

Doporučil bych však použít (jak jste řekl) IF/ELSE Když spojíte dvě podmínky, jako je tato, můžete si často vynutit neoptimální plány. např. ve vašem příkladu byste to mohli zjednodušit na schéma takto:

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

Tím se jednoduše vyplní jeden ze sloupců čísly 0-2047, která se v každém opakují 4krát (jen pro některé příklady dat). Pak Pokud vytvořím dvě procedury, jednu, která používá 'IF/ELSE' jednu, která kombinuje výše uvedená kritéria:

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

Protože ke kompilaci dotazů dojde pouze jednou (pokud výslovně neřeknete jinak), optimalizátor nevybere jiný plán v závislosti na tom, zda postupu předáte 0 nebo předáte ID> 0, takže platí obojí:

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

Dá tento plán:

Druhý postup je schopen odhadnout nejlepší plán provedení mnohem lépe, takže spusťte toto:

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

Poskytuje následující plán:

Příklady ze skutečného světa se budou samozřejmě lišit a já jsem záměrně vytvořil příklad, který dokazuje můj názor. Je trochu větší úsilí duplikovat velké množství kódu pomocí IF/ELSE , ale často to stojí za to.



  1. MySQL – SQL_BIG_SELECTS

  2. Lepší způsob, jak spouštět více příkazů MySQL pomocí skriptu Shell

  3. Výpočet vzdálenosti mezi PSČ v PHP

  4. Nelze nainstalovat PostgreSQL:Při spouštění runtime instalačního programu Microsoft VC++ v systému Windows XP došlo k chybě