2010-07-05 3 views
7

Возможно ли создать предложение ORDER BY, чтобы обеспечить следующие критерии для двух полей (оба типа INT), которые называются child и parent соответственно для этого примера.Комплексный порядок TSQL по предложению

  1. parent ссылки child, но может быть пустым.
  2. Родитель может иметь несколько детей; у ребенка только один родитель.
  3. Ребенок не может быть родителем самого себя.
  4. Должно существовать хотя бы один ребенок без родителя.
  5. Каждое значение child должно появиться до того, как оно появится в parent в упорядоченном результирующем наборе.

Я с трудом с точки 5.

Образец неупорядоченный данные:

child parent 
------------ 
1  NULL 
3  5 
4  2 
2  5 
5  NULL 

Очевидно ни ORDER BY a, b или ORDER BY b, a работы. На самом деле, чем больше я думаю об этом, я не уверен, что это вообще можно сделать. Учитывая эти ограничения, очевидными случаями, такими как:

child parent 
------------ 
1  2 
2  1 

не допускаются, поскольку они нарушают правила 3 ​​и 4 (и, очевидно, 5).

Итак, что я пытаюсь достичь, и если да, то как? Платформа SQL Server 2005.

Обновление: Желаемый порядок сортировки для данных выборки:

child parent 
------------ 
1  NULL 
5  NULL 
2  5 
3  5 
4  2 

Для каждой строки, которая определяет ненулевое значение в родительской колонке, значение уже присутствует int дочерний столбец.

+0

Не мог бы вы показать пример данные в требуемом порядке, пожалуйста? Это поможет. –

+0

Добавлено согласно вашему запросу, Брайан. –

ответ

6

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

create table node (id int, parent int) 
insert into node values (1, null) 
insert into node values (2, 5) 
insert into node values (3, 5) 
insert into node values (4, 2) 
insert into node values (5, null) 
insert into node values (6, 4); 

with node_cte (id, depth) as (
    select id, 0 from node where parent is null 
    union all 
    select node.id, node_cte.depth + 1 
    from node join node_cte on node.parent = node_cte.id  
) 

select node.* 
from node 
join node_cte on node_cte.id=node.id 
order by node_cte.depth asc 
+1

Ahh, рекурсивные CTE. Есть ли что-то, чего они не могут сделать? –

1

Вы не сможете сделать это с помощью предложения ORDER BY, поскольку требование 5 указывает, что порядок чувствителен к иерархии данных. В иерархических данных SQL Server 2005 обычно рассматриваются рекурсивные CTE; возможно, кто-то здесь предоставит соответствующий код для этого случая.

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