在 SQL 语句中使用子查询的替代方案?

Swa*_*ati 4 sql subquery query-optimization

我有两张桌子:

TableA: (a temporary table)
ItemId (int)

TableB:
ItemId (int), ParentID (int)
Run Code Online (Sandbox Code Playgroud)

我想检索表 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 ) 
Run Code Online (Sandbox Code Playgroud)

就像这个一样:

SELECT b.ItemID 
FROM TableB b
WHERE b.ItemID IN ( SELECT * FROM TableA)
AND b.ParentID NOT IN ( SELECT * FROM TableA )
Run Code Online (Sandbox Code Playgroud)

我对这两个查询都不满意,特别是因为使用了 NOT IN/IN。有没有办法在没有他们的情况下做到这一点?也许是一种不需要子查询的更干净的方法?

样本数据:

Table A
-------
2
3
5
6

Table B
--------
1 | NULL
2 | 1
3 | 1
4 | 3
5 | 3
6 | 3
Run Code Online (Sandbox Code Playgroud)

期望的结果:

2
3
Run Code Online (Sandbox Code Playgroud)

谢谢

one*_*hen 5

没有子查询:

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;
Run Code Online (Sandbox Code Playgroud)

...但是您对子查询的恐惧合理吗?:) 我发现这个等效查询更容易阅读和理解:

SELECT ItemID
  FROM TableA
INTERSECT 
SELECT ItemID
  FROM TableB
 WHERE NOT EXISTS (
                   SELECT * 
                     FROM TableA AS a
                    WHERE a.ItemID = TableB.ParentID
                  );
Run Code Online (Sandbox Code Playgroud)