以下查询
SELECT child.*
FROM [nested-set] AS parent
JOIN (
SELECT [lft] AS parentLft, [rgt] AS parentRgt
FROM [nested-set] WHERE [id] = 3
) AS parent2 ON 1=1
JOIN [nested-set] AS child ON child.[lft] BETWEEN parent.[lft] AND parent.[rgt]
WHERE parent.[lft] >= parentLft AND parent.[rgt] < parentRgt AND parent.[id] > 1
GROUP BY child.[id]
HAVING COUNT(child.[id]) = 1
ORDER BY child.[lft] ASC
在嵌套集模型中获取节点的子节点,在MySQL和SQLite上运行完全正常(当然使用不同的列引用)但是为了使它在MS SQL Server上工作,我必须添加所有列GROUP BY子句。由于此查询应该在不同的表上运行,这些表只有id,lft和rgt列共同必须指定所有列,每次都是过度杀伤。有解决方案吗?
答案 0 :(得分:1)
您可以使用返回所需Id的子查询,然后将主表链接到该子查询。
这样您就不需要在外部查询中指定列。
SELECT t.*
FROM(
SELECT child.id
FROM [nested-set] headparent
JOIN [nested-set] parent ON (parent.lft >= headparent.lft AND parent.rgt < headparent.rgt)
JOIN [nested-set] child ON (child.lft BETWEEN parent.lft AND parent.rgt)
WHERE headparent.id = 3
AND parent.id > 1
GROUP BY child.id
HAVING count(*) = 1
) q
JOIN [nested-set] t ON t.id = q.id
ORDER BY t.lft ASC;
由于这几乎是“旧标准SQL”(f.e。不使用窗口函数),因此它也适用于MySql或SQLite。
发布脚本:
我想知道是否可以使用EXISTS。
从下面的实验来看,确实如此。如果您不使用GROUP BY
但是i.m.h.o.,第一种方法是更直接的方法来实现它。
declare @NestedSet table (id int, lft int, rgt int, colA int);
insert into @NestedSet (id,lft,rgt,colA) values
(1,3,5,100),
(2,4,5,200),
(3,3,6,300),
(4,3,5,400),
(5,4,6,500);
select *
from @NestedSet t
where exists (
select 1
from @NestedSet headparent
join @NestedSet parent on (parent.lft >= headparent.lft and parent.rgt < headparent.rgt and parent.id > 1)
where headparent.id = 3
and t.lft between parent.lft and parent.rgt
having count(*) = 1
);