2016-06-10 20 views
0

我想編寫一個腳本,有兩個不同的領域,並列出了哪些值將在兩者之間在IE擴大了全範圍的兩個字段

之間的列表
ID|Start#|End# 
1 |1  |5 
2 |6  |8 
3 |9  |10 

將顯示爲

ID |FullRange 
1 |1 
1 |2 
1 |3 
1 |4 
1 |5 
2 |6 
2 |7 
2 |8 
3 |9 
3 |10 
+0

請告訴我們您的最佳嘗試。 –

+0

創建一個商店presodure或表函數誰recive這兩個值,並在de函數內建立一個WHILE LOOP插入每個值在表變量,然後選擇所有記錄插入表變量 – Byron

+0

@Byron雖然這將是一種方式做到這一點,我不會推薦它。如果可以以基於集合的方式完成,則應避免使用「CURSOR」或「WHILE」循環。 –

回答

0

您可以使用遞歸來做到這一點。

WITH cte ([ID], [END#], FullRange) 
AS 
(
-- Anchor member definition 
SELECT ee.[ID] 
,ee.[END#] 
,ee.[START#] as FullRange 
FROM [master].[dbo].[test] ee 
where ee.[START#] < ee.[END#] 
UNION ALL 

-- Recursive member definition 
SELECT e.[ID] 
,e.[END#] 
,FullRange +1 
FROM [master].[dbo].[test] e inner join cte 
on e.id = cte.id and FullRange +1 <= cte.END# 
) 
-- Statement that executes the CTE 
SELECT ID,FullRange 
FROM cte 
ORDER BY ID 

結果如下圖所示:

ID FullRange 
1 1 
1 2 
1 3 
1 4 
1 5 
2 6 
2 7 
2 8 
3 9 
3 10 
0

您可以使用Tally Table從生成數[Start#][End#]

WITH E1(N) AS(-- 10^1 = 10 rows 
    SELECT 1 FROM(VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))t(N) 
), 
E2(N) AS(SELECT 1 FROM E1 a CROSS JOIN E1 b), -- 10^2 = 100 rows 
E4(N) AS(SELECT 1 FROM E2 a CROSS JOIN E2 b), -- 10^4 = 10,000 rows 
CteTally(N) AS(
    SELECT TOP(SELECT MAX([End#] - [Start#]) + 1 FROM Tbl) 
     ROW_NUMBER() OVER(ORDER BY(SELECT NULL)) - 1 
    FROM E4 
) 
SELECT 
    t.ID, 
    FullRange = t.[Start#] + ct.N 
FROM Tbl t 
CROSS JOIN CteTally ct 
WHERE t.[Start#] + ct.N <= t.[End#] 
ORDER BY t.ID, FullRange 

ONLINE DEMO

0
declare @tbl table (id int, start int, [end] int) 
insert @tbl values (1, 1, 5), (2, 6, 8), (3, 9 , 10); 


;with t(c) as 
(
    select * from (values (0), (1), (2), (3), (4), (5), (6), (7), (8), (9)) a(b) 
), 
x(y) as 
(
    select t1.c * 100 + t2.c * 10 + t3.c 
    from t t1 
    cross join t t2 
    cross join t t3 
) 
select t.id, x.y 
from x 
join @tbl t on t.start <= x.y and t.[end] >= x.y 
order by t.id, x.y