我有一个CMS系统,它有一个包含父子关系和内容表的站点地图表。如果相应的站点地图条目或其任何父项已被禁用,有时我不希望在查询中包含内容。
基本表结构是:
tb_Sitemap :id,parent_id,已启用
tb_Content :id,sitemap_id
所以我希望能够在我的查询中添加一些内容:
SELECT * FROM tb_Content WHERE {tb_Sitemap.enabled and any or all parents are also enabled}
我知道我需要使用CTE,但我不确定如何将这些添加到WHERE子句或如何进行。
我猜我需要做类似的事情,但不确定如何添加到WHERE子句:
;WITH cte (enabled)
AS
(
SELECT enabled FROM tb_Content WHERE id = tb_Content.sitemap_id
UNION ALL
SELECT CASE WHEN b.enabled != 1 THEN 0 ELSE a.enabled FROM tb_Sitemap a
INNER JOIN cte b ON a.parent_id = b.id
)
SELECT enabled FROM cte
示例数据:
tb_Sitemap
tbl_Content
答案 0 :(得分:4)
-- A little test data.
declare @tb_Sitemap as table ( id int, parent_id int null, enabled bit )
insert into @tb_Sitemap ( id, parent_id, enabled ) values
( 1, NULL, 1 ), ( 2, 1, 1 ), ( 3, 2, 1 ),
( 4, 1, 0 ), ( 5, 4, 1 ), ( 6, 5, 1 )
declare @tb_Content as table ( sitemap_id int )
insert into @tb_Content ( sitemap_id ) values ( 3 ), ( 6 )
-- Query the little beggars.
; with CTE as (
-- Start at the root(s).
select id, parent_id, enabled, enabled as summary_enabled
from @tb_Sitemap
where parent_id is NULL
union all
-- Add one generation at a time.
select S.id, s.parent_id, s.enabled, cast( case when s.enabled = 1 and CTE.summary_enabled = 1 then 1 else 0 end as bit )
from CTE inner join
@tb_Sitemap as S on S.parent_id = CTE.id
)
select *, case when summary_enabled = 1 and sitemap_id is not NULL then '< winner!' else '' end as include
from CTE left outer join
@tb_Content as C on C.sitemap_id = CTE.id