采用以下两个表变量,是否有任何(更快/更短/更有效)的替代方法可以删除@tbl_big
中@tbl_small
内不存在的任何数据?原因是我有大量的数据选择,并且基于可选参数(在程序中)我在向用户呈现之前进一步过滤数据。
userId
列在物理表中编入索引,这些表变量列是从中填充的。
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
我确实想知道INTERSECT
或EXCEPT
是否会这样做,但无法弄明白。
更新: EXCEPT
/ INTERSECT
调查结果作为答案。我不确定从编码角度来看是否有更短的路径......?
答案 0 :(得分:2)
通常,存在或左外连接都可以解决问题。
DELETE b FROM @tbl_big b
WHERE NOT EXISTS (
SELECT 1 FROM @tbl_small s
WHERE s.userID = b.userID);
OR
DELETE b FROM @tbl_big b
LEFT OUTER JOIN @tbl_small s
ON s.userID = b.userID
WHERE s.userID IS NULL;
答案 1 :(得分:1)
这是现代的:)但我不确定它比不存在的删除更快:
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
答案 2 :(得分:1)
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;
答案 3 :(得分:0)
我终于想出了EXCEPT
,虽然它不容易阅读!
DELETE
b
FROM
@tbl_big b INNER JOIN
(
SELECT
*
FROM
@tbl_big EXCEPT
SELECT
userID
FROM
@tbl_small) s ON s.userID = b.userID;
我现在也意识到INTERSECT
实际上会删除错误的一半数据(例如数据NOT IN @tbl_small
)