2012-04-16 26 views
6

Aquí está la estructura de ejemplo de la tabla:Cómo mostrar parentID recursiva en una sola columna en SQL

ID Name  ParentID 
----------------------- 
1  Ancestor  NULL 
2  GrandFather 1 
3  GrandMother 1 
4  Child   3 

Estoy intentando escribir una consulta que devolvería

ID  Name  Family 
---------------------------- 
1  Ancestor 
2  GrandFather Ancestor 
3  GrandMother Ancestor 
4  Child  Ancestor^GrandMother 

El complicado La parte es que quiero mostrar la familia de todas las filas y en orden descendente.

Si alguien me puede apuntar en la dirección correcta, sería apreciado :)

EDITAR :: Esta es la consulta real, pero sigue la misma idea. devuelve un error en la línea: marketparent.family + '^' + t2.marketGroupName porque no puede encontrar marketparent

WITH marketparent (marketGroupID,parentGroupID, marketGroupName,family) 
AS 
(
SELECT marketGroupID, 
     parentGroupID, 
     marketGroupName, 
     '' as family 
FROM EVE.dbo.invMarketGroups 
WHERE parentGroupID IS NULL 
UNION ALL 

    SELECT t2.parentGroupID, 
    t2.marketGroupID, 
    t2.marketGroupName, 
    marketparent.family + '^'+ t2.marketGroupName 
    FROM EVE.dbo.invMarketGroups as t2 
    INNER JOIN marketparent as mp 
    ON mp.marketGroupID = t2.parentGroupID 
) 

-- Statement using the CTE 

SELECT TOP 10 * 
FROM marketparent; 
+3

La solución dependerá del DBMS que utilice. SQL Server, Oracle, MySQL o ....? –

+0

estoy usando SQL Server 2008 – darthun08

+0

Use el alias 'mp' en lugar de' marketparent'. –

Respuesta

5

No ha especificado su DBMS, así que estoy asumiendo PostgreSQL

WITH RECURSIVE fam_tree (id, name, parent, family) as 
(
    SELECT id, 
     name, 
     parentid, 
     ''::text as family 
    FROM the_unknown_table 
    WHERE parent IS NULL 

    UNION ALL 

    SELECT t2.id, 
     t2.name, 
     t2.parentid, 
     fam_tree.family || '^' || t2.name 
    FROM the_unknown_table t2 
    INNER JOIN fam_tree ON fam_tree.id = t2.parentid 
) 
SELECT * 
FROM fam_tree; 

Este es el SQL estándar (excepto el tipo de conversión ::text) que debería funcionar con muy pocos cambios en la mayoría del DBMS moderno.

Editar:

Para SQL Server que necesitaría para reemplazar el carácter concatention estándar con no-estandar de Microsoft + (y lo que necesita para eliminar la palabra clave recursive que es requerido por el estándar, pero por alguna extraña razón rechazada por SQL Server)

WITH fam_tree (id, name, parent, family) as 
(
    SELECT id, 
     name, 
     parentid, 
     '' as family 
    FROM the_unknown_table 
    WHERE parent IS NULL 

    UNION ALL 

    SELECT t2.id, 
     t2.name, 
     t2.parentid, 
     fam_tree.family + '^' + t2.name 
    FROM the_unknown_table t2 
    INNER JOIN fam_tree ON fam_tree.id = t2.parentid 
) 
SELECT * 
FROM fam_tree; 
+0

ahora si quiero generar la familia de una fila que está en otra tabla pero tiene una clave externa a esta tabla, ¿puedo agregar algún código en la última consulta o tengo que poner algo en el WITH? – darthun08

+0

fam_tree.family + '^' + t2.name devuelve el error: El identificador de varias partes "fam_tree.family" no pudo vincularse. Probablemente esto se deba a que no especifiqué el idioma correcto en mi pregunta. Estoy usando MS SQL Server 2008, y en cuanto al resto, no sé qué información necesitaría: P – darthun08

+0

@ user1336586: hmm, 'fam_tree.family + '^' + t2.name' debería funcionar para todos Lo sé. Como no tengo tus tablas, supongo que hay un error tipográfico. Prueba a eliminar la definición de columna en la parte con: 'con fam_tree como (...' ' –

0

puede utilizar un recursivo Common Table Expression.

declare @T table 
(
    ID int, 
    Name nvarchar(15), 
    ParentID int 
); 

insert into @T values 
(1,  N'Ancestor',  NULL), 
(2,  N'GrandFather', 1), 
(3,  N'GrandMother', 1), 
(4,  N'Child',   3); 

with C as 
(
    select T.ID, 
     T.Name, 
     T.ParentID, 
     cast(N' ' as nvarchar(max)) as Family 
    from @T as T 
    where T.ParentID is null 
    union all 
    select T.ID, 
     T.Name, 
     T.ParentID, 
     C.Family+'^'+C.Name 
    from @T as T 
    inner join C 
     on T.ParentID = C.ID 
) 
select C.ID, 
     C.Name, 
     stuff(C.Family, 1, 2, '') as Family 
from C; 
+0

muchas gracias, voy a intentar que – darthun08

+0

@user esto funcionó para usted? Veo que tuvo algunos problemas con la respuesta aceptada que creo que se solucionó en mi respuesta. –

+0

no, no funcionó. Encontré otra solución donde creo una nueva tabla y actualizo los valores de forma iterativa. Si tiene tiempo, busque mi nueva publicación, aún necesito ayuda con lo mismo. – darthun08

0
select T.ID, T.Name, (select name from table where ID=T.ParentID)as Family 
from table T 
+0

su consulta parece que solo devuelve el nombre principal de cada fila. Es un buen intento, pero estoy buscando la ruta completa :) – darthun08

Cuestiones relacionadas