2011-12-19 22 views

Respuesta

9

Quizás haya mejores formas pero esto parece ser suficiente para hacer el trabajo.

declare @T table 
(
    ID int, 
    Name varchar(10), 
    HID HierarchyID 
) 

insert into @T values 
(1, 'Craig', '/'), 
(2, 'Steve', '/1/'), 
(3, 'John', '/1/1/'), 
(4, 'Sam', '/2/'), 
(5, 'Matt', '/2/1/'), 
(6, 'Chris', '/2/1/1/') 

select * 
from @T 
where HID.GetDescendant(null, null) not in (select HID 
              from @T) 

Resultado:

ID   Name  HID 
----------- ---------- --------------------- 
3   John  0x5AC0 
6   Chris  0x6AD6 

actualización 2012-05-22

consulta anterior fallará si números de nodo no está en una secuencia ininterrumpida. Aquí hay otra versión que debería encargarse de eso.

declare @T table 
(
    ID int, 
    Name varchar(10), 
    HID HierarchyID 
) 

insert into @T values 
(1, 'Craig', '/'), 
(2, 'Steve', '/1/'), 
(3, 'John', '/1/1/'), 
(4, 'Sam', '/2/'), 
(5, 'Matt', '/2/1/'), 
(6, 'Chris', '/2/1/2/') -- HID for this row is changed compared to above query 

select * 
from @T 
where HID not in (select HID.GetAncestor(1) 
        from @T 
        where HID.GetAncestor(1) is not null) 
1

ya que sólo necesita hojas y que no es necesario obtenerlos de un ancestro específica, una consulta no recursiva simple como esto debe hacer el trabajo:

SELECT * FROM YOUR_TABLE PARENT 
WHERE 
    NOT EXISTS (
     SELECT * FROM YOUR_TABLE CHILD 
     WHERE CHILD.HierarchyId = PARENT.Id 
    ) 

En la llanura Inglés: seleccionar cada fila sin una fila de niños

Esto asume que su HierarchyId es una LLAVE EXTRAÑA hacia Id, no la "ruta" completa como se muestra en su ejemplo. Si no es así, esto es probablemente lo primero que debe corregir en su modelo de base de datos.

--- --- EDITAR

OK, aquí es la consulta MS SQL Server-specific que realmente funciona:

SELECT * FROM YOUR_TABLE PARENT 
WHERE 
    NOT EXISTS (
     SELECT * FROM YOUR_TABLE CHILD 
     WHERE 
      CHILD.Id <> PARENT.Id 
      AND CHILD.HierarchyId.IsDescendantOf(PARENT.HierarchyId) = 1 
    ) 

Tenga en cuenta que la IsDescendantOf considera cualquier fila descendiente de sí mismo , entonces también necesitamos el CHILD.Id <> PARENT.Id en la condición.

+0

Estoy bastante seguro de que el OP está utilizando el 'HierarchyID' tipo de datos de SQL Server 2008, lo que explica la representación inusual (ver http://msdn.microsoft.com/en-us/magazine/cc794278 .aspx). –

+0

@DanielPratt Ahh ... Veo ahora que la pregunta se volvió a etiquetar como [sql-server]. –

+0

Gracias por responder a Branko, pero en mi ejemplo, el campo Id es un número entero y el HierarchyId es un sql HierarchyId por lo que no se pueden comparar. ¿Estás diciendo que necesito cambiar la clave de la tabla para que sea el hierarchyId? – Eric

1

Hola, yo uso este y funciona perfectamente para mí.

CREATE TABLE [dbo].[Test]([Id] [hierarchyid] NOT NULL, [Name] [nvarchar](50) NULL) 
DECLARE @Parent AS HierarchyID = CAST('/2/1/' AS HierarchyID) -- Get Current Parent 
DECLARE @Last AS HierarchyID 
SELECT @Last = MAX(Id) FROM Test WHERE Id.GetAncestor(1) = @Parent -- Find Last Id for this Parent 

INSERT INTO Test(Id,Name) VALUES(@Parent.GetDescendant(@Last, NULL),'Sydney') -- Insert after Last Id 
Cuestiones relacionadas