Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Câu lệnh Sql Case trong Sql IN

Bạn có thể làm điều đó bằng cách sử dụng OR :

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

Tuy nhiên, tôi khuyên bạn nên sử dụng (như bạn đã nói) IF/ELSE , khi kết hợp hai điều kiện như thế này, bạn thường có thể buộc phải lập kế hoạch dưới mức tối ưu. Ví dụ:Trong ví dụ của bạn, bạn có thể đơn giản hóa điều này thành một lược đồ như sau:

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

Điều này chỉ đơn giản là điền vào một trong các cột có các số 0-2047 được lặp lại 4 lần mỗi cột (chỉ đối với một số dữ liệu ví dụ). Sau đó, Nếu tôi tạo hai thủ tục, một thủ tục sử dụng 'IF / ELSE', một thủ tục kết hợp các tiêu chí như trên:

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

Vì việc biên dịch các truy vấn sẽ chỉ xảy ra một lần (trừ khi bạn nói rõ ràng khác), trình tối ưu hóa sẽ không chọn một kế hoạch khác tùy thuộc vào việc bạn chuyển 0 hay chuyển ID> 0 cho quy trình, vì vậy cả hai điều sau:

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

Sẽ đưa ra kế hoạch này:

Thủ tục thứ hai có thể ước tính kế hoạch thực thi tốt nhất tốt hơn nhiều, vì vậy hãy chạy nó:

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

Đưa ra kế hoạch sau:

Các ví dụ trong thế giới thực rõ ràng sẽ khác nhau, và tôi đã cố tình xây dựng một ví dụ để chứng minh quan điểm của tôi. Sẽ tốn nhiều công sức hơn một chút để sao chép nhiều mã bằng cách sử dụng IF/ELSE , nhưng nó thường đáng giá.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ngày truy xuất trong máy chủ sql, CURRENT_TIMESTAMP so với GetDate ()

  2. Công cụ khôi phục sao lưu SQL để sửa chữa bản sao lưu SQL bị hỏng - Đánh giá sản phẩm - Bài đăng của khách của Daniel Jones

  3. Trả lại Tên máy chủ cục bộ trong SQL Server bằng @@ SERVERNAME

  4. Hai câu lệnh cập nhật dưới đây khác nhau như thế nào trong SQL?

  5. Xoay vòng và dấu phẩy Giá trị được phân tách