Alternative moderne à SUPPRIMER … O WH … PAS DANS (…)?

Prenant les deux variables de table suivantes, existe-t-il une alternative (plus rapide / plus courte / plus efficace) pour supprimer datatables de @tbl_big qui n'existent pas dans @tbl_small ? La raison en est que j'ai un grand choix de données, et en fonction des parameters optionnels (dans une procédure), je filter datatables plus avant avant de les présenter à l'user.

La colonne userId est indexée dans la table physique à partir de laquelle les colonnes de variable de table sont renseignées.

 DECLARE @tbl_big TABLE (userID int); INSERT INTO @tbl_big (userID) VALUES (1),(5),(10),(20),(30),(40),(60),(100); DECLARE @tbl_small TABLE (userID int); INSERT INTO @tbl_small (userID) VALUES (1),(5),(10),(20) -- this deletes 30,40,60,100 from @tbl_big DELETE FROM @tbl_big WHERE (userID NOT IN (SELECT userID FROM @tbl_small)); SELECT * from @tbl_big; 

http://www.sqlfiddle.com/#!6/d41d8/12674

Je me suis demandé si INTERSECT ou EXCEPT pourrait le faire mais ne peut pas les comprendre.

Mise à jour: les résultats INTERSECT / INTERSECT inclus comme réponse. Je ne suis pas sûr que le encoding soit plus court …?

Typiquement, existe ou joint externe gauche ferait l'affaire.

 DELETE b FROM @tbl_big b WHERE NOT EXISTS ( SELECT 1 FROM @tbl_small s WHERE s.userID = b.userID); 

OU

 DELETE b FROM @tbl_big b LEFT OUTER JOIN @tbl_small s ON s.userID = b.userID WHERE s.userID IS NULL; 

Eh bien, c'est moderne 🙂 mais je ne suis pas sûr que ce soit plus rapide qu'une suppression où n'existe pas:

 DECLARE @tbl_big TABLE (userID int) DECLARE @tbl_small TABLE (userID int) INSERT INTO @tbl_big (userID) VALUES (1),(5),(10),(20),(30),(40),(60),(100) INSERT INTO @tbl_small (userID) VALUES (1),(5),(10),(20) ;with deleting as ( SELECT * from @tbl_big except select * from @tbl_small) DELETE b FROM @tbl_big b where exists ( select * from deleting c where c.userID = b.userID) SELECT * from @tbl_big 
 DECLARE @tbl_big TABLE (userID int) DECLARE @tbl_small TABLE (userID int) DECLARE @tbl_new TABLE (userID int) INSERT INTO @tbl_big (userID) VALUES (1),(5),(10),(20),(30),(40),(60),(100) INSERT INTO @tbl_small (userID) VALUES (1),(5),(10),(20) INSERT INTO @tbl_new SELECT userID FROM @tbl_big INTERSECT SELECT userID FROM @tbl_small; SELECT * from @tbl_new; 

J'ai finalement pensé EXCEPT , mais ce n'est pas vraiment plus facile à lire!

 DELETE b FROM @tbl_big b INNER JOIN ( SELECT * FROM @tbl_big EXCEPT SELECT userID FROM @tbl_small) s ON s.userID = b.userID; 

Je me rends count maintenant INTERSECT supprimerait la mauvaise moitié des données (par exemple datatables NOT IN @tbl_small )