Как я могу заменить это где предложение с объединением?

8

Обычно, когда я вижу SQL, который использует что-то вроде:

select * from employees where epmloyeeTypeId in (select id from type where name = 'emp') 

Я заменяю на whereэто:

select e.* from employees e 
inner join type t on t.id=e.epmloyeeTypeId and t.name = 'emp'

Можно ли сделать то же самое с обратным в случае, если это not in(как показано ниже), а не inпредложение?

INSERT into Subscriptions(ProjectId, RecordTypeCID, NTID, Active, Added, LastUpdate, UpdateBy)   
 SELECT @ProjectId, RecordTypeCID, @NTID, 1, GETDATE(), GETDATE(), @NTID  
 FROM @Check CHK  
 WHERE CHK.ActiveStatus=1  
        And Not Exists (SELECT SubscriptionId FROM Subscriptions  
                        WHERE ProjectId=@ProjectId           
                        and NTID=@NTID          
                        and RecordTypeCID = CHK.RecordTypeCID
                        )  

Дополнительные соображения

Я могу сделать это:

INSERT INTO Subscriptions(ProjectId, RecordTypeCID, NTID,Active, Added, LastUpdate, UpdateBy)   
SELECT @ProjectId, RecordTypeCID, @NTID,1, GETDATE(), GETDATE(), @NTID  
FROM @Check CHK
    LEFT JOIN Subscriptions subs ON subs.RecordTypeCID = CHK.RecordTypeCID
        AND NTID = @NTID
        AND ProjectId = @ProjectId

        AND CHK.ActiveStatus = 1
        AND subs.SubscriptionId IS NULL
kacalapy
источник

Ответы:

6

Да. Вы можете заменить LEFT JOIN ... WHERE NULL. Выполняет намного быстрее

INSERT INTO Subscriptions(
    ProjectId, RecordTypeCID, NTID,
    Active, Added, LastUpdate, UpdateBy)   
SELECT @ProjectId, RecordTypeCID, @NTID,
    1, GETDATE(), GETDATE(), @NTID  
FROM @Check CHK
LEFT JOIN Subscriptions subs
    ON subs.RecordTypeCID = CHK.RecordTypeCID
        AND NTID = @NTID
        AND ProjectId = @ProjectId
WHERE CHK.ActiveStatus = 1
    AND subs.SubscriptionId IS NULL
Эрик Хамфри - Лотсхелп
источник
какая производительность отличается между двумя? Я думаю, что объединения намного быстрее, чем использование в (...) или не в (...), никогда не думал о существовании (...), есть идеи?
Какалапы
также могу ли я включить все в объединение, см. мои правки внизу вопроса
kacalapy
1
Вы должны иметь предложение WHERE, как я уже сказал.
Эрик Хамфри - LotsAhelp
4
"Выполняет намного быстрее"? Чем не существует или не в? Если НЕ В, да. Если не существует, довольно равно.
ГБН
1
Пример или на SO
gbn
7

Ваш NOT EXISTS более эффективен в большинстве случаев.

LEFT JOIN внутренне сопоставляет все строки, затем фильтрует в IS NULL. НЕ СУЩЕСТВУЕТ, не. Это умножение строк также происходит во всем коде, основанном на JOIN, поэтому вам может потребоваться дополнительный агрегат (DISTINCT) для исправления вывода.

NOT IN, как правило, неправильно, потому что NULL не вызывают совпадения.

Вы также можете использовать EXCEPT, который дает тот же план, что и NOT EXISTS.

SELECT @ProjectId, RecordTypeCID, @NTID,1, GETDATE(), GETDATE(), @NTID  
FROM @Check CHK
EXCEPT
SELECT @ProjectId, RecordTypeCID, @NTID,1, GETDATE(), GETDATE(), @NTID  
FROM Subscriptions
WHERE ProjectId=@ProjectId           
and NTID=@NTID          

К вашему сведению, в соответствии со стандартом SQL-92 (стр. 191, случай 3a) бит SELECT в EXISTS игнорируется.

ГБН
источник