2011-12-19 30 views

Trả lời

9

Có lẽ có những cách tốt hơn nhưng đường nối này để thực hiện công việc.

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) 

Kết quả:

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

Cập nhật 2012-05-22

Query trên sẽ thất bại nếu số nút không phải là trong một chuỗi không gián đoạn. Đây là một phiên bản khác nên chú ý đến điều đó.

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

Vì bạn chỉ cần lá và bạn không cần phải nhận được chúng từ một tổ tiên cụ thể, một truy vấn không đệ quy đơn giản như thế này nên thực hiện công việc:

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

Trong tiếng Anh đơn giản: chọn mỗi hàng không có hàng con.

Điều này giả định HierarchyId của bạn là một khóa NGOÀI TRỜI đối với Id, không phải toàn bộ "đường dẫn" như được trình bày trong ví dụ của bạn. Nếu không, đây có lẽ là điều đầu tiên bạn nên sửa trong mô hình cơ sở dữ liệu của bạn.

--- EDIT ---

OK, đây là MS SQL query Server-cụ thể mà thực sự hoạt động:

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 
    ) 

Lưu ý rằng IsDescendantOf xem xét bất kỳ hàng một hậu duệ của bản thân , vì vậy chúng tôi cũng cần số CHILD.Id <> PARENT.Id trong điều kiện.

+0

Tôi khá chắc chắn OP đang sử dụng 'kiểu dữ liệu HierarchyID' của SQL Server 2008, điều này giải thích các đại diện khác thường (xem http://msdn.microsoft.com/en-us/magazine/cc794278 .aspx). –

+0

@DanielPratt Ahh ... Tôi thấy bây giờ câu hỏi đã được gắn lại là [sql-server]. –

+0

Cảm ơn bạn đã phản hồi Branko, nhưng trong ví dụ của tôi trường Id là một số nguyên và HierarchyId là một phân cấp sql để chúng không thể so sánh được. Bạn có nói rằng tôi cần phải thay đổi chìa khóa của bảng để được các hierarchyId? – Eric

1

Xin chào, tôi sử dụng tính năng này và hoạt động hoàn hảo cho tôi.

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 
Các vấn đề liên quan