2017-02-20 1 views
-1

У меня есть таблица, как это,
Как получить количество уровней в sub_of с использованием SQL Server 2008?

|id | Name |sub_of| 
|1 |Level 1A| 0 | 
|2 |Level 1B| 0 | 
|3 |Level 1C| 0 | 
|4 |Level 1D| 0 | 
|5 |Level 2A| 1 | 
|6 |Level 2B| 2 | 
|7 |Level 2C| 3 | 
|8 |Level 3C| 7 | 
|9 |Level 4C| 8 | 
|10 |Level 5C| 9 | 
|11 |Level 3B| 6 | 

Я этот случай

  • А имеют 2 уровня
  • В имеет 3 уровня
  • с имеют 5 уровней
  • d имеют 1 уровень

Sub_of является идентификатором предыдущего уровня. Имя не содержит имя sub_of (т.е. A не содержит весь уровень A).

Мне нужен максимальный уровень sub_of. Пожалуйста, дайте несколько идей.

+0

Обеспечить образец вывода результатов, о том, как это должно выглядеть? – balaji

+0

Просто я нуждаюсь в том, чтобы иметь максимальное количество строк и их количество. Это означает, что значение sub_of 0 является нашей главной строкой, а другие строки являются вспомогательными строками. –

+0

есть поле, которое идентифицирует, например, все строки уровня A? – McNets

ответ

1

Вам нужен уникальный идентификатор для каждого уровня (A, B, C, ...)

Используя рекурсивный запрос CTE я использовал первый идентификатор где sub_of = 0 как уникальный идентификатор:

;WITH tree AS 
(
    SELECT c1.id, c1.name, c1.sub_of, [id_level] = c1.id, [level] = 1 
    FROM dbo.[btree2] c1 
    WHERE c1.sub_of = 0 
    UNION ALL 
    SELECT c2.id, c2.name, c2.sub_of, [id_level] = tree.[id_level], [level] = tree.[level] + 1 
    FROM dbo.[btree2] c2 INNER JOIN tree ON c2.sub_of = tree.id 
) 
SELECT t1.id, t1.sub_of, t1.name, t1.id_level, t1.level 
FROM tree t1 
    INNER JOIN (SELECT id_level, MAX(level) AS level FROM tree GROUP BY id_level) t2 
    ON t1.id_level = t2.id_level AND t1.level = t2.level 
ORDER BY id_level, level 
OPTION (MAXRECURSION 0) 
; 

Затем просто получите MAX (уровень) для каждой группы.

+----+--------+----------+----------+-------+ 
| id | sub_of | name  | id_level | level | 
+----+--------+----------+----------+-------+ 
| 5 | 1 | Level 2A |  1 | 2 | 
| 11 | 6 | Level 3B |  2 | 3 | 
| 10 | 9 | Level 5C |  3 | 5 | 
| 4 | 0 | Level 1D |  4 | 1 | 
+----+--------+----------+----------+-------+ 

Проверьте это здесь: http://rextester.com/KIEY97438

2

Рекурсивный CTE является вашим другом ...

Создать и заполнить таблицу выборки (Пожалуйста сохранить нас этот шаг в ваших будущих вопросов)

DECLARE @T as TABLE 
(
    id int, 
    Name varchar(10), 
    sub_of int 
) 

INSERT INTO @T VALUES 
(1 ,'Level 1A',0), 
(2 ,'Level 1B',0), 
(3 ,'Level 1C',0), 
(4 ,'Level 1D',0), 
(5 ,'Level 2A',1), 
(6 ,'Level 2B',2), 
(7 ,'Level 2C',3), 
(8 ,'Level 3C',7), 
(9 ,'Level 4C',8), 
(10 ,'Level 5C',9), 
(11 ,'Level 3B',6) 

КТР:

;WITH CTE AS 
(
    SELECT id, Name, Sub_Of, 0 As Level 
    FROM @T 
    WHERE Sub_Of = 0 

    UNION ALL 
    SELECT t.id, t.Name, t.Sub_Of, Level + 1 
    FROM @T as t 
    INNER JOIN CTE ON t.Sub_Of = CTE.id 
) 

Запрос:

SELECT * 
FROM CTE 
ORDER BY Level DESC 

Результаты:

id Name  Sub_Of Level 
10 Level 5C 9  4 
9 Level 4C 8  3 
11 Level 3B 6  2 
8 Level 3C 7  2 
7 Level 2C 3  1 
6 Level 2B 2  1 
5 Level 2A 1  1 
1 Level 1A 0  0 
2 Level 1B 0  0 
3 Level 1C 0  0 
4 Level 1D 0  0 
+0

Уверенный мой будущий вопрос должен иметь эти шаги. Спасибо. –

+0

Отлично. Рад, что смог помочь. –

Смежные вопросы