Выбор таблицы карт таблицы отец-сын - PullRequest
1 голос
/ 15 сентября 2011


У меня есть таблица категорий с отношениями отца и сына, которая выглядит примерно так:

Имя таблицы:

tblCategories

Столбцы:

catID
catFatherID - Этот столбец связан с catID

Мне нужно выбрать для каждой категории детей всей семьи(включая себя) следующим образом:
Исходные строки таблицы:

| catID | catFatherID |
= = = = = = = = = = = =
|   1   | null        |
|   2   |  1          |
|   3   |  1          |
|   4   |  2          |
|   5   |  3          |
|   6   |  4          |

Что я хочу получить:

| Category ID | Family Category ID |
= = = = = = = = = = = = = =  = = = =
| 1 | 1 | (Yes, I want it to include itself in the return family members)
| 1 | 2 |
| 1 | 3 |
| 1 | 4 |
| 1 | 5 |
| 1 | 6 |
| 2 | 2 |
| 2 | 4 |
| 2 | 6 |
| 3 | 3 |
| 3 | 5 |
| 4 | 4 |
| 4 | 6 |
| 5 | 5 |
| 6 | 6 |

Спросите, не сделал ли янедостаточно объяснить.

Ответы [ 3 ]

1 голос
/ 15 сентября 2011

A CTE подойдет для решения этой проблемы.Хитрость заключается в том, чтобы сохранить root ID при выполнении CTE.

Оператор SQL

;WITH q AS (
  SELECT  root = catID, catID, catFatherID
  FROM    tblCategories
  UNION ALL
  SELECT  q.root, c.catID, c.catFatherID
  FROM    q 
          INNER JOIN tblCategories c ON c.catFatherID = q.catID 

)
SELECT  root, catID
FROM    q
ORDER BY
        root, catID

Тестовый скрипт

;WITH tblCategories (catID, catFatherID) AS (
  SELECT  1, NULL
  UNION ALL SELECT 2, 1
  UNION ALL SELECT 3, 1
  UNION ALL SELECT 4, 2
  UNION ALL SELECT 5, 3
  UNION ALL SELECT 6, 4
)
, q AS (
  SELECT  root = catID, catID, catFatherID
  FROM    tblCategories
  UNION ALL
  SELECT  q.root, c.catID, c.catFatherID
  FROM    q 
          INNER JOIN tblCategories c ON c.catFatherID = q.catID 

)
SELECT  root, catID
FROM    q
ORDER BY
        root, catID
1 голос
/ 15 сентября 2011

Вы должны использовать рекурсивный SQL с CTE.

with families(id, parent_id) as (
  select * from tblCategories where id = __initial_id__
  union all
  select t.* from tblCategories as t inner join families as f on t.catFatherID = f.id 
)
 select * from families

См. статью на MSDN

0 голосов
/ 15 сентября 2011
WITH n(catId, catFatherId) AS 
   (SELECT catId, catFatherId 
    FROM tblCategories 
        UNION ALL
    SELECT n1.catId, n1.catFatherId 
    FROM tblCategories as n1, n
    WHERE n.catId = n1.catFatherId)
SELECT * FROM n
...