2010-07-05 13 views
7

Es posible crear una cláusula ORDER BY para garantizar los siguientes criterios para dos campos (ambos de tipo INT), llamados child y parent respectivamente para este ejemplo.Orden de TSQL complejo por cláusula

  1. parent referencias child, pero puede ser nulo.
  2. Un padre puede tener varios hijos; un niño solo un padre.
  3. Un niño no puede ser padre de sí mismo.
  4. Debe existir al menos un hijo sin un padre.
  5. Cada valor de child debe aparecer antes de que aparezca en parent en el conjunto de resultados ordenados.

estoy teniendo dificultad con el punto 5.

muestra de datos sin ordenar:

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

Obviamente ni ORDER BY a, b o ORDER BY b, a trabajo. De hecho, cuanto más lo pienso, no estoy seguro de que se pueda siquiera hacer. Dadas las restricciones, los casos obvios tales como:

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

no están permitidos porque viola la regla 3 y 4 (y, obviamente, 5).

Entonces, ¿qué es lo que estoy tratando de lograr, y de ser así cómo? Plataforma es SQL Server 2005.

Actualización: orden deseado para los datos de la muestra:

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

Para cada fila que define un valor no nulo en la columna de la matriz, el valor ya ha estado presente int la columna hija

+0

Podría mostrar los datos de la muestra en el orden deseado, por favor? Eso sería una ayuda. –

+0

Agregado según su solicitud, Brian. –

Respuesta

6

Se puede usar un CTE recursiva para encontrar la "profundidad" de cada nodo, y el orden por el que:

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 recursivos. ¿Hay algo que no puedan hacer? –

1

No podrá hacerlo con una cláusula 'ORDER BY' porque el requisito 5 especifica que la orden es sensible a la jerarquía de datos. En SQL Server 2005, los datos de la jerarquía generalmente se tratan usando CTE recursivos; tal vez alguien aquí proporcione el código apropiado para este caso.

Cuestiones relacionadas