我有一个数字清单。我想从三个表的列表中确定它们在哪个表中,并在单个结果集中返回表名和编号。
Nums: 1,2,3,4,8,9
Tables: tb1, tb2, tb3
通常,我会查询每个表并将它们全部Union
一起查询,但是我想知道是否有一种方法可以使语句使列表更小,因为它有望在很大程度上提高效率。数据。这是我想做的一个例子:
Checking tb1 first, I find that 1,2,3 are present.
Then check tb2 for the remaining numbers (4,8,9).
If none of the numbers are found, then check tb3, otherwise the query should end.
以下是两种可能的回报:
TableName | Num *|* TableName | Num
---------------- *|* ----------------
tb1 | 1 *|* tb1 | 1
tb1 | 2 *|* tb1 | 2
tb1 | 3 *|* tb1 | 3
tb3 | 4 *|* tb2 | 4
tb3 | 8 *|* tb3 | 9
tb3 | 9 *|* *** 8 wasn't found
有没有办法做到这一点?还是Union
还是最好的方法?
答案 0 :(得分:1)
只是为了好玩,我编写了两个查询,一个使用UNION
方法,另一个尝试使用上面定义的逻辑,即检查table1,然后在table2中查找其余项,然后在table3中查找,依此类推
这是我的脚本:
DECLARE @table1 TABLE (id INT PRIMARY KEY);
DECLARE @table2 TABLE (id INT PRIMARY KEY);
DECLARE @table3 TABLE (id INT PRIMARY KEY);
INSERT INTO @table1 SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 9;
INSERT INTO @table2 SELECT 3 UNION ALL SELECT 4;
INSERT INTO @table3 SELECT 6 UNION ALL SELECT 8;
SELECT id, 'table1' AS found FROM @table1 WHERE id IN (1, 2, 3, 4, 5, 6, 7, 8, 9)
UNION
SELECT id, 'table2' AS found FROM @table2 WHERE id IN (1, 2, 3, 4, 5, 6, 7, 8, 9)
UNION
SELECT id, 'table3' AS found FROM @table3 WHERE id IN (1, 2, 3, 4, 5, 6, 7, 8, 9)
ORDER BY id;
DECLARE @search TABLE (id INT PRIMARY KEY);
INSERT INTO @search SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9;
WITH
nt1 AS (SELECT * FROM @search s EXCEPT SELECT * FROM @table1),
nt2 AS (SELECT * FROM nt1 EXCEPT SELECT * FROM @table2)
SELECT s.id, 'table1' AS found FROM (SELECT * FROM @search INTERSECT SELECT * FROM @table1) s
UNION ALL
SELECT s.id, 'table2' AS found FROM (SELECT * FROM nt1 INTERSECT SELECT * FROM @table2) s
UNION ALL
SELECT s.id, 'table3' AS found FROM (SELECT * FROM nt2 INTERSECT SELECT * FROM @table3) s
ORDER BY id;
每种方法的结果都相同,请注意这不会告诉您不匹配的地方,所以可能不是理想的选择吗?
然后,我将整个脚本视为执行计划。这不是火箭科学,并且有一个很强的论点是,引入新的@search
表是“欺骗”,而且使用表变量来保存数据是错误的(即使是临时表也应使用物理表) ,并且表中的数据量太小等等。
但是,在这个有缺陷的实验中,我发现UNION
方法的速度是后者的两倍以上。