我有两张桌子:
TableA: (a temporary table)
ItemId (int)
TableB:
ItemId (int), ParentID (int)
我想检索表A中的所有项目,其中表A中任何项目的ParentID不作为ItemID存在。 (即我想获得TableA中项目的根目录)
此查询执行我想要的操作:
SELECT a.ItemID
FROM TableA a
INNER JOIN TableB b ON a.ItemId = b.ItemID
WHERE b.ParentID NOT IN ( SELECT * from TableA )
就像这一样:
SELECT b.ItemID
FROM TableB b
WHERE b.ItemID IN ( SELECT * FROM TableA)
AND b.ParentID NOT IN ( SELECT * FROM TableA )
我对其中任何一个查询都不满意,特别是因为使用了NOT IN / IN。没有它们有没有办法做到这一点?也许更简洁的方式不需要子查询?
示例数据:
Table A
-------
2
3
5
6
Table B
--------
1 | NULL
2 | 1
3 | 1
4 | 3
5 | 3
6 | 3
期望的结果:
2
3
由于
答案 0 :(得分:4)
查看Select all rows from one table that don't exist in another table,了解使用
进行此类查询的5种不同方法不在
不存在
左和右连接
外部申请(2005年))
除外(2005 +)
这是一个可以运行的脚本
CREATE TABLE #TableA( ItemId int)
INSERT #TableA values(1)
INSERT #TableA values(2)
INSERT #TableA values(3)
INSERT #TableA values(4)
INSERT #TableA values(5)
INSERT #TableA values(6)
CREATE TABLE #TableB( ItemId int, ParentID int)
INSERT #TableB values(1,1)
INSERT #TableB values(2,2)
INSERT #TableB values(4,3)
INSERT #TableB values(5,4)
这将为父母
SELECT a.ItemID
FROM #TableA a
LEFT JOIN #TableB b ON a.ItemId = b.ParentID
WHERE b.ItemID IS NULL
SELECT a.ItemID
FROM #TableA a
WHERE NOT EXISTS (SELECT 1 FROM #TableB b WHERE a.ItemId = b.ParentID)
输出
ItemID
5
6
答案 1 :(得分:4)
没有子查询:
SELECT ItemID
FROM TableA
INTERSECT
SELECT b.ItemID
FROM TableB AS b
LEFT OUTER JOIN TableA AS a
ON b.ParentID = a.ItemID
WHERE a.ItemID IS NULL;
...但你对子查询的恐惧是否理性? :)我发现这个等效的查询更容易阅读和理解:
SELECT ItemID
FROM TableA
INTERSECT
SELECT ItemID
FROM TableB
WHERE NOT EXISTS (
SELECT *
FROM TableA AS a
WHERE a.ItemID = TableB.ParentID
);
答案 2 :(得分:0)
您可以使用外连接。像这样:
SELECT a.ItemID
FROM TableA a
INNER JOIN TableB b ON a.ItemId = b.ItemID
LEFT JOIN TableB parentB on a.ItemID = parentB.ParentID
WHERE parentB.ParentID IS NULL
答案 3 :(得分:0)
您的表A和B似乎存储了树结构。我将表A解释为"节点" (存储树的元素)和表B为"边缘" (将节点链接到它的父节点)。内部连接变体非常优雅,因为它涵盖了所有的情况,没有边缘到父母","边缘到PrantID null"和"边缘到不存在的父母"立刻。 欢呼声