Рекурсивный запрос, чтобы проверить, что все родители включены - PullRequest
1 голос
/ 08 февраля 2012

У меня есть система CMS, в которой есть таблица карты сайта с отношениями родитель-потомок и таблица содержимого.Иногда я не хочу включать контент в запросы, если соответствующая запись карты сайта или какой-либо из его родителей отключены.

Основная структура таблицы:

tb_Sitemap :id, parent_id, enabled

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

  • id: 1, parent_id: null, включено: 1
  • id: 2, parent_id: 1, включено: 1
  • id: 3, parent_id: 2, включено: 1
  • id: 4, parent_id: 1, включено: 0
  • id: 5, parent_id: 4, включено: 1
  • id: 6, parent_id: 5, включено: 1

tbl_Content

  • sitemap_id: 3 (это будет выглядеть потому, что sitemap_Идентификатор: 3 включен, как и все его родители)
  • sitemap_id: 6 (это не будет отображаться, потому что хотя sitemap_id: 6 включен, один из его родителей нет)

1 Ответ

4 голосов
/ 08 февраля 2012
-- 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...