2011-07-07 30 views
6

Tôi có một bảng có một số con của đối tượng chính. Bất kỳ đứa trẻ có thể xảy ra nhiều hơn một lần, và có một cột lần xuất hiện có chứa con số đó, vì vậy dữ liệu trong bảng là một cái gì đó như:Chọn cùng một hàng nhiều lần

ChildID | ParentID | Occurences 
------------------------------- 
     1 |  1 |  2 
     2 |  1 |  2 
     3 |  2 |  1 
     4 |  2 |  3 

tôi cần để có được một danh sách của tất cả các trẻ em, với mỗi đứa trẻ xuất hiện số corect lần trong kết quả, một cái gì đó giống như

IDENT | ChildID | ParentID 
-------------------------- 
    1 |  1 |  1 
    2 |  1 |  1 
    3 |  2 |  1 
    4 |  2 |  1 
    5 |  3 |  2 
    6 |  4 |  2 
    7 |  4 |  2 
    8 |  4 |  2 

tôi có thể làm điều này với một con trỏ mà vòng bảng và chèn như nhiều hàng như cần thiết, nhưng tôi không nghĩ rằng đó là giải pháp tốt nhất khả thi.

Thanks for the help


Tạo kịch bản bao gồm:

DECLARE @Children TABLE (ChildID int, ParentID int, Occurences int) 

INSERT @Children 
SELECT 1, 1, 2 UNION ALL 
SELECT 2, 1, 2 UNION ALL 
SELECT 3, 2, 1 UNION ALL 
SELECT 4, 2, 3 
+1

Bạn có phiền không nếu tôi hỏi bạn tại sao bạn cần làm điều này? Có thể có một cách tốt hơn so với việc chọn cùng một hàng nhiều lần. – EdoDodo

+0

Tôi cần tạo một hàng cho mỗi đứa trẻ, bởi vì có một số dữ liệu phụ có thể khác nhau. – SWeko

Trả lời

7
;with C as 
(
    select ChildID, 
     ParentID, 
     Occurences - 1 as Occurences 
    from @Children 
    union all 
    select ChildID, 
     ParentID, 
     Occurences - 1 as Occurences 
    from C 
    where Occurences > 0 
) 
select row_number() over(order by ChildID) as IDENT, 
     ChildID, 
     ParentID 
from C 
order by IDENT 
+0

Thx, điều đó đã làm thủ thuật – SWeko

+0

lừa tuyệt vời :) – SMK

+0

Một điều nữa, trong trường hợp của tôi số Occurences là nhỏ (10 đầu) nhưng nếu số lượng trong hàng trăm, điều này sẽ vượt quá giới hạn đệ quy. – SWeko

4
;WITH CTEs 
AS 
(
    SELECT 1 [Id] 
    UNION ALL 
    SELECT [Id] + 1 FROM CTEs WHERE [Id] < 100 
) 
SELECT ROW_NUMBER() OVER(ORDER BY c1.ChildID, c1.ParentID) [rn] 
    , c1.ChildID, c1.ParentID 
FROM CTEs ct 
JOIN @Children c1 ON c1.Occurences >= ct.[Id] 

Một cách khác để tạo ra chuỗi được sử dụng bảng được xác định trước, ví dụ master.dbo.spt_values:

SELECT ROW_NUMBER() OVER(ORDER BY c1.ChildID, c1.ParentID) [rn] 
    , c1.ChildID, c1.ParentID 
FROM master.dbo.spt_values ct 
JOIN @Children c1 ON c1.Occurences > ct.number 
    AND ct.type = 'P' 
+0

Thật tuyệt, điều này về cơ bản là gia nhập bảng nguồn với một bảng số, với một điều kiện tham gia tốt đẹp. – SWeko

+0

Trong trường hợp của tôi số Occurences là nhỏ (10 ngọn) nhưng nếu số lượng trong hàng trăm, điều này sẽ vượt quá giới hạn đệ quy. Điều đó có thể được sidestepped nếu bảng số được tạo trước. – SWeko

+0

hoặc sidestepped với "tùy chọn (MAXRECURSION 0)" –

Các vấn đề liên quan