扩展两个字段之间的完整范围列表

时间:2016-06-10 03:46:57

标签: sql tsql

我试图编写一个带有两个不同字段的脚本,并列出它们之间的值.I /

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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

答案 2 :(得分: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