Recursive query to check that all parents are enabled

青春壹個敷衍的年華 提交于 2019-12-13 00:12:45

问题


I have a CMS system which has a sitemap table with a parent-child relationship and a content table. Sometimes I don't want to include content in queries if it's corresponding sitemap entry or any of its parents is disabled.

The basic table structure is:

tb_Sitemap: id, parent_id, enabled

tb_Content: id, sitemap_id

So I want to be able to add something to my queries like this:

SELECT * FROM tb_Content WHERE {tb_Sitemap.enabled and any or all parents are also enabled}

I know I need to use a CTE but I am unsure about how to add these to a WHERE clause or how to go about it.

I am guessing I need do something like, but not sure how to add to a WHERE clause:

;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

Sample data:

tb_Sitemap

  • id: 1, parent_id: null, enabled: 1
  • id: 2, parent_id: 1, enabled: 1
  • id: 3, parent_id: 2, enabled: 1
  • id: 4, parent_id: 1, enabled: 0
  • id: 5, parent_id: 4, enabled: 1
  • id: 6, parent_id: 5, enabled: 1

tbl_Content

  • sitemap_id: 3 (this would appear because sitemap_id:3 is enabled as is all of its parents)
  • sitemap_id: 6 (this will not appear because although sitemap_id:6 is enabled, one of its parents is not)

回答1:


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


来源:https://stackoverflow.com/questions/9185281/recursive-query-to-check-that-all-parents-are-enabled

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!