我有下表:
ID NAME PARENT_ID ISDELETED ISINEDIT
1 JJ NULL 1 0
2 AR 1 0 0
3 PR 2 0 0
4 DR NULL 0 1
我需要获取的是SELECT查询,该查询将仅返回具有ISDELETED 0和ISINEDIT 0且其父母或祖父母也为0的行
我目前有:
;WITH ChildParent AS
(
SELECT
a.id,
a.name,
a.isinedit,
a.parent_id,
a.isdeleted
FROM dbo.table
WHERE isdeleted = 0 AND isinedit = 0
UNION ALL
SELECT
a.id,
a.name,
a.isinedit,
a.parent_id,
a.isdeleted
FROM dbo.table a
INNER JOIN ChildParent cp ON a.parent_id = cp.id
WHERE a.isdeleted = 0 AND a.isinedit = 0
)
SELECT
id,
name,
parent_id,
isinedit,
isdeleted
FROM ChildParent
但是由于某种原因,它会返回双行
答案 0 :(得分:1)
您需要向isdeleted = 0 AND isinedit = 0
源添加相同的INNER JOIN childParent CP
谓词。
...但是,如果您这样做的话,您会非常轻率地进行CTE查询,并且如果必须一遍又一遍地重复同一件事,那么可能会有更好的方法。
...有! SELECT
查询可以具有多个CTE表达式:
;
WITH filtered AS
(
SELECT
a.id,
a.name,
a.parent_id,
FROM
dbo.Table
WHERE
IsDeleted = 0
AND
IsInEdit = 0
)
WITH cte AS
(
SELECT
a.id,
a.name,
a.parent_id
FROM
filtered
UNION ALL
SELECT
a.id,
a.name,
a.parent_id
FROM
filtered
INNER JOIN cte ON a.parent_id = cte.id
)
SELECT
*
FROM
cte
ORDER BY
id
答案 1 :(得分:1)
我认为这比您想象的要复杂。据我所知,您需要首先遍历每个节点的整个父级层次结构,然后然后检查是否有任何父级不满足规则(您可以通过在之后停止进行一些优化) 遇到了第一个不符合要求的父母。
您还需要跟踪原始节点,以便可以在外部查询中进行正确过滤(这样可以避免当前获取的重复项)。
我的查询短语为:
with cte as (
select
t.*,
t.id original_id,
0 lvl,
1 is_ok
from dbo.table t
where isdeleted = 0 and isinedit = 0
union all
select
t.*,
c.original_id,
c.lvl + 1,
case when t.isdeleted = 0 and t.isinedit = 0 then 1 else 0 end
from dbo.table t
inner join cte c on c.parent_id = t.id
where c.is_ok = 1
)
select *
from cte c
where
c.lvl = 0
and not exists (
select 1 from cte c1 where c1.original_id = c.original_id and c1.is_ok = 0
)
请注意,无论树中存在多少级别,该查询都将起作用(如果您有100多个级别,则需要在查询末尾添加option(maxrecursion 0)
。
答案 2 :(得分:0)
如果您首先在CTE中创建干净的数据集,则这些类型的查询会更容易。它消除了所有CTE查询中的多余过滤子句。
在这种情况下,返回所有未删除且不在编辑中的行。接下来将获取您的数据。祖父母INNER JOIN父母INNER JOIN CHILD
;WITH GoodDataRows AS
(
SELECT
a.id,
a.name,
a.isinedit,
a.parent_id,
a.isdeleted
FROM dbo.table
WHERE isdeleted = 0 AND isinedit = 0
)
SELECT
*
FROM GoodDataRows gp
INNER JOIN GoodDataRows p ON p.parent_id = gp.id
INNER JOIN GoodDataRows c on c.parent_id = p.id