【发布时间】:2015-03-07 15:10:29
【问题描述】:
我有一个表示层次结构的表,因此它同时具有id 和parent_id。此层次结构只有两个级别,并且父级在parent_id 中具有空值。我正在尝试为父级具有特定属性的层次结构中的每个项目获取记录。以这个数据为例:
CREATE TABLE t (id int, parent_id int, property bit);
INSERT INTO t VALUES
(1, null, 0),
(2, 1, null),
(3, null, 1),
(4, 3, null),
(5, null, 1);
我想找回:
======
| ID |
======
| 3 |
| 4 |
| 5 |
======
我可以像这样使用UNION 来做到这一点:
SELECT
id
FROM
t
WHERE
property = 1 AND parent_id is null
UNION
SELECT
child.id
FROM
t parent
INNER JOIN t child
ON parent.id = child.parent_id
WHERE
parent.property = 1
ORDER BY
id;
但是,这会扫描表 3 次。我试图对此进行一些优化,所以尝试了这个:
SELECT
ISNULL(child.id, parent.id)
FROM
t parent
LEFT JOIN t child
ON parent.id = child.parent_id
WHERE
parent.property = 1
但这只是给了我:
======
| ID |
======
| 4 |
| 5 |
======
没有返回第 3 行,因为 LEFT JOIN 没有为第 3 行提供单独的行,因为它与第 4 行中的 parent_id 匹配。有没有办法修改 LEFT JOIN 以提供我需要的额外行?是否有另一种方法来执行此查询,而不像 UNION 方法那样扫描表三次?
【问题讨论】:
-
一个连接会链接两个表,它不会返回两次。
-
无论如何,左连接也在做两次表扫描
-
@Jaques 好的,我错了,左连接进行了两次表扫描,而联合进行了三次。它有点复杂,因为涉及到索引,但这并不是问题的重点。
标签: sql-server sql-server-2008 tsql join