2017-01-06 29 views
5

Tôi có một SourceTable như thế này với tên 2 cột:Làm thế nào tôi có thể viết một thủ tục lưu trữ SQL Server để có được kết quả sau?

Col 1 | Col 2 
------------------ 
    A  | 2 
    B  | 3 
    C  | 4 
    D  | 2 
    E  | 1 
    F  | 0 

Cột đầu tiên có một số bức thư, và cột thứ hai mang tần số của nó.

Chúng tôi cần viết quy trình được lưu trữ và nhận kết quả đầu ra theo số TargetTable như thế này.

Chúng tôi KHÔNG ĐƯỢC sử dụng bất kỳ vòng lặp nào hoặc lặp lại cho việc này.

Col 1 
----- 
    A 
    A 
    B 
    B 
    B 
    C 
    C 
    C 
    C 
    D 
    D 
    E 

Trả lời

4

Làm thế nào về CTE đệ quy?

with x as (
     select col1, 1 as i, col2 as lim 
     from t 
     where col2 > 0 
     union all 
     select col1, i + 1, lim 
     from x 
     where i + 1 <= lim 
    ) 
select col1 
from x 
order by col1; 
+0

col1 ----- Một B C D E D C C C B B Một Đây là những gì tôi nhận được cho mã của bạn –

+1

@CodeFearer Bạn chỉ cần thêm mệnh đề 'order by'. – iamdave

+0

chỉ cần thêm lệnh 1 để có được chính xác như bạn muốn – GuidoG

0

Giả có một giá trị tối đa thấp được biết đến với col2 (trong trường hợp này 10):

select Col1 from tbl 
    inner join (values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) T(n) 
    on T.n <= tbl.Col2 
0

Tôi muốn sử dụng một bảng số. Ví dụ: xem: https://dba.stackexchange.com/questions/11506/why-are-numbers-tables-invaluable

Đây là bảng Numbers có một cột Number có giá trị từ 1 đến một số tiền đủ lớn. Cá nhân tôi có một bảng số với 100 nghìn hàng. Có thể generate it on the fly, nhưng nó có ích trong nhiều trường hợp, vì vậy tôi có một bảng vĩnh viễn.

SELECT 
    A.Col1 
FROM 
    SourceTable 
    CROSS APPLY 
    (
     SELECT SourceTable.Col1 
     FROM Numbers 
     WHERE Numbers.Number <= SourceTable.Col2 
    ) AS A 
ORDER BY Col1; 
0

Nếu bạn không muốn sử dụng một CTE đệ quy hoặc có một bảng số, bạn có thể sử dụng master..spt_values để tạo ra con số của bạn dành cho bạn:

declare @t table(Col1 nvarchar(1), Col2 int); 
insert into @t values 
('A',2),('B',3),('C',4),('D',2),('E',1),('F',0); 

with rn as 
(   -- This sub select simply makes sure you only get the maximum number required. 
select top (select max(Col2) from @t) row_number() over (order by (select null)) as rn 
from master..spt_values t1 
    cross join master..spt_values t2 
) 
select t.Col1 
from @t t 
    inner join rn 
    on(t.Col2 >= rn.rn) 
order by t.Col1 
Các vấn đề liên quan