Нужна помощь с SQL-запросом (SQL Server 2005) для преобразования этих данных.

Вот упрощенный взгляд на таблицу, которая у меня есть

Категория

  • CategoryId
  • CategoryName
  • ParentCategoryId

Как вы можете видеть, таблица каталога является таблицей, ссылающейся на себя, поэтому ее можно повторять, начиная с 0, который является поддельной «корневой» категорией (с таким же успехом может быть null, но это не так).

Пример данных:

1, Apples, 0
5, Yummy, 1
10, Really Yummy, 5
15, Yucky, 0
18, Some Sub Cat, 15
20, Some Deep Sub Cat, 18
25, Some Deep Sub Cat 2, 18

Самая глубокая иерархия любой категории может быть глубиной 4, и я пытаюсь получить результат, который выглядит следующим образом:

CatId, [up to 4 deep of category names on the hierarchy in separate columns, or null if none]
1, Apples, NULL, NULL, NULL
5, Apples, Yummy, NULL, NULL
10, Apples, Yummy, Really Yummy, NULL
15, Apples, Yucky, NULL, NULL
18, Apples, Yucky, Some Sub Cat, NULL
20, Apples, Yucky, Some Sub Cat, Some Deep Sub Cat
25, Apples, Yucky, Some Sub Cat, Some Deep Sub Cat 2

Этот SQL близок, но он генерирует его задом наперед, выровненным по левому краю

select c1.categoryid, c1.name, c2.name, c3.name, c4.name
from category c1
    left outer join category c2
        on c1.parentcategoryid = c2.categoryid
    left outer join category c3
        on c2.parentcategoryid = c3.categoryid
    left outer join category c4
        on c3.parentcategoryid = c4.categoryid

У кого-нибудь из гениев SQL есть хорошие идеи?


person TheSoftwareJedi    schedule 21.07.2009    source источник


Ответы (1)


select c1.CategoryId as id,
       c1.CategoryName as n1,
       c2.CategoryName as n2,
       c3.CategoryName as n3,
       c4.CategoryName as n4
from            Category c1
left outer join Category c2 on c2.ParentCategoryId = c1.CategoryId
left outer join Category c3 on c3.ParentCategoryId = c2.CategoryId
left outer join Category c4 on c4.ParentCategoryId = c3.CategoryId
where c1.parentcategoryid = 0;

(согласно вашему редактированию: у вас только что в соединениях перевернуты ParentCategoryId и CategoryID.)

person Carl Manaster    schedule 21.07.2009
comment
Довольно близко ... Пара изменений. Требуется предложение where, где c1.parentcategoryid = 0, или он печатает результаты бездействия. Тогда ему нужен оператор case, возможно, чтобы определить идентификатор, который нужно показать (самый глубокий уровень)? Мысли? - person TheSoftwareJedi; 22.07.2009
comment
Спасибо; Я добавил предложение WHERE, которое вы предлагаете. Я бы избегал оператора CASE - я не думаю, что SQL очень элегантно обрабатывает логику условного потока такого рода - и просто написал бы остальные три запроса по своему усмотрению. Я знаю, что некоторые разработчики ненавидят дублирование настолько, что начинают писать и поддерживать оператор case, но для меня это лучше подходит для языка. - person Carl Manaster; 22.07.2009
comment
тогда это неверно, напечатанный идентификатор категории является корневым идентификатором категории. Мне нужно было распечатать категорию самого глубокого уровня. Оператор case работал нормально. - person TheSoftwareJedi; 22.07.2009
comment
Это не учитывает нелистовые категории - person TheSoftwareJedi; 05.09.2009