Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Pernyataan Kasus Sql dalam Sql IN

Anda dapat melakukannya menggunakan OR :

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

Namun, saya sarankan menggunakan (seperti yang Anda katakan) IF/ELSE , saat menggabungkan dua kondisi seperti ini, Anda sering kali dapat memaksakan rencana yang kurang optimal. misalnya Dalam contoh Anda, Anda dapat menyederhanakannya menjadi skema sebagai berikut:

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

Ini hanya mengisi salah satu kolom dengan angka 0-2047 yang masing-masing diulang 4 kali (hanya untuk beberapa contoh data). Kemudian Jika saya membuat dua prosedur, yang menggunakan 'IF/ELSE' yang menggabungkan kriteria seperti di atas:

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

Karena kompilasi kueri hanya akan terjadi sekali (kecuali jika Anda secara eksplisit mengatakan sebaliknya), pengoptimal tidak akan memilih paket yang berbeda bergantung pada apakah Anda meneruskan 0 atau meneruskan ID> 0 ke prosedur, jadi kedua hal berikut:

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

Akan memberikan rencana ini:

Prosedur kedua dapat memperkirakan rencana eksekusi terbaik dengan lebih baik, jadi jalankan ini:

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

Memberikan rencana berikut:

Contoh dunia nyata jelas akan bervariasi, dan saya sengaja membuat contoh yang membuktikan maksud saya. Sedikit lebih banyak upaya untuk menduplikasi banyak kode dengan menggunakan IF/ELSE , tetapi sering kali sepadan.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tidak ada snap-in yang terdaftar untuk Windows PowerShell versi 2

  2. Memasukkan pyodbc.Binary data (BLOB) ke dalam kolom gambar SQL Server

  3. Prosedur atau fungsi tersimpan mengharapkan parameter yang tidak disediakan

  4. Versi SQL Server yang digunakan tidak mendukung tipe data datetime2?

  5. Lulus Kamus<string,int> ke Prosedur Tersimpan T-SQL