2015-11-18 3 views
1

У меня есть таблица, как это в моем SQL Server 2008.запросов к группе и сортировать иерархические данные

ID  ParentID Level  Code Name   Description 
1  1   1   EXP  Expenses  -- 
2  1   2   PEXP Project Exp -- 
3  1   2   IEXP Indirect Exp. -- 
4  4   1   INC  Incomes  -- 
5  1   2   MEXP Misc. Exp.  -- 
6  2   3   MCOST Material Cost -- 
7  4   2   IINC Indirect Inc. -- 
8  6   4   TCOS Tiles Cost -- 

Я хочу, чтобы запрос, который выбрать все строки в иерархическом порядке. (Стоимость плиток по материальной стоимости, материальной стоимости по проектным расходам, расходы по проектам по расходам и т. Д. В таблице может быть не более 5 уровней. В таблице указано 2000 строк.)

Возможно ли это в SQL-запросе?

Ожидаемый результат должен выглядеть следующим образом:

ID  ParentID Level  Code Name   Description 
1  1   1   EXP  Expenses  -- 
3  1   2   IEXP Indirect Exp. -- 
5  1   2   MEXP Misc. Exp.  -- 
2  1   2   PEXP Project Exp -- 
6  2   3   MCOST Material Cost -- 
8  6   4   TCOS Tiles Cost -- 
4  4   1   INC  Incomes  -- 
7  4   2   IINC Indirect Inc. -- 
+0

Какие СУБД вы используете? Можете ли вы также показать нам ожидаемый результат? – jarlh

+0

Привет, я обновил свой вопрос. –

+0

Вы пробовали CTE? –

ответ

1

Вы можете использовать Recursive CTE:

;WITH CTE_Tree AS (
    -- Anchor member: get all parent nodes, initialize order_key 
    SELECT ID, ParentID, Level, Code, Name, 
      CAST(ID AS VARCHAR(MAX)) AS order_key 
    FROM mytable 
    WHERE Level = 1 

    UNION ALL 

    -- Recursive member: get child node of previous node and update 
    -- order _key of branch 
    SELECT t1.ID, t1.ParentID, t1.Level, t1.Code, t1.Name, 
      order_key = t2.order_key + '.' + CAST(t1.Level AS VARCHAR(MAX)) 
    FROM mytable AS t1 
    INNER JOIN CTE_Tree AS t2 ON t1.ParentID = t2.ID AND t1.Level > t2.Level 
) 
SELECT * 
FROM CTE_Tree 
ORDER BY order_key,Code 

CTE используется для рекурсивного вычисления ключа заказа. Первой цифрой ключа заказа является ID родительского узла. Это связано с тем, что мы хотим, чтобы все узлы из ветви первого родителя упорядочивались над узлами ветви следующего родителя.

Вторая, третья и т. Д., Цифра - это просто уровень узла. Этот уровень способ 2 узлов упорядочены именно после того, как родительский узел, уровень 3 узлов дальше, и т.д.

Demo here

+0

Большое спасибо; Он работал очень хорошо, –

0

Исходя из того, что у вас есть максимум 5 уровней, это должно работать.

При выборе значения только на первом уровне, а затем использовать внутренние соединения пойти вниз уровни, вы должны получить ожидаемый результат:

SELECT MyTable5.* FROM MyTable as MyTable1 
    INNER JOIN MyTable AS MyTable2 ON MyTable2.ParentId = MyTable1.Id 
    INNER JOIN MyTable AS MyTable3 ON MyTable3.ParentId = MyTable2.Id 
    INNER JOIN MyTable AS MyTable4 ON MyTable4.ParentId = MyTable3.Id 
    INNER JOIN MyTable AS MyTable5 ON MyTable5.ParentId = MyTable4.Id 
WHERE MyTable1.Level = 1 
ORDER BY MyTable1.Id, MyTable5.Level 
Смежные вопросы