繁体   English   中英

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

[英]Alternative to using subqueries in SQL statements?

我有两张桌子:

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

谢谢

看一下从一个表中选择另一个表中不存在的所有行 ,看看使用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

没有子查询:

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
                  );

您的表A和B似乎存储树结构。 我将表A解释为“节点”(存储树的元素),将表B解释为“边缘”(将节点链接到它的父节点)。 内连接变体非常优雅,因为它涵盖了所有“无边缘到父”,“边缘到PrantID null”和“边缘到非存在父”的情况。 干杯

您可以使用外连接。 像这样的东西:

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 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM