Множественное условие запроса Microsoft SQL

#sql #performance

#sql #Производительность

Вопрос:

У меня есть таблица атрибутов, в которой есть набор атрибутов, идентифицируемых уникальным номером, за которым следует их описание — Пример схемы

 ID - AttributeName
  

с некоторыми примерами данных ниже

 1 = FirstName
2 = LastName
3 = Phone
  

Затем у меня есть таблица employees, которая для простоты имеет следующую схему

 ID - PersonID
AttribueID - INT Foreign key to the above attributes table
  

Мне нужно создать сохраненный процесс, который при заданном условии будет возвращать записи на основе одного из следующих условий

Если я передам 1 хранимой процедуре, процедура должна вернуть все записи из таблицы Person, которые соответствуют идентификатору атрибута 1 (Имя) Если я передам 2 хранимой процедуре, процедура должна вернуть все записи из таблицы Person, которые * НЕ * соответствуют идентификатору атрибута 1 (Имя) Если я передам 3 в хранимую процедуру, процедура должна вернуть все записи из таблицы Person

Я мог бы сделать следующее, но чувствую, что это не лучший способ, которым это можно было бы выполнить

 DECLARE @IntID INT = 1 -- Set as 1 just for exmple

IF @IntID =1
BEGIN

    SELECT * FROM Person where AttributeID IN (SELECT ID from Attributes Where ID =1) -- match on attribute 1
END
ELSE IF @IntID = 2
BEGIN
    SELECT * FROM Person where AttributeID NOT IN (SELECT ID from Attributes Where ID =1) -- do not match on attribute 1

END
ELSE
BEGIN
    SELECT * FROM Person where AttributeID IN (SELECT ID from Attributes) -- return match on all attributes
END
  

Приведенный выше пример содержит чрезвычайно простую инструкцию SELECT — в реальном SQL существует гораздо больший набор

Заранее спасибо

Ответ №1:

Если вы не хотите использовать динамический sql, вы можете попробовать это. И ваш запрос слишком прост, что для оптимизации производительности вы можете обратиться к табличным индексам для этого.

 DECLARE @IntID INT = 1 -- Set as 1 just for exmple

IF @IntID = 1 OR @IntID = 2
BEGIN

    SELECT A.* 
    FROM Person A
    LEFT JOIN Attributes B ON A.AttributeID = B.ID AND B.ID = 1
    WHERE 
    A.AttributeID IS CASE @IntID WHEN 1 THEN NOT NULL WHEN 2 THEN NULL END 
END
ELSE
BEGIN
    SELECT A.* 
    FROM Person A
    INNER JOIN Attributes B ON A.AttributeID = B.ID
END
  

Комментарии:

1. Объединение нескольких обращений в один универсальный выбор может привести к неоптимальному плану выполнения, я бы вообще рекомендовал избегать этого.