如何获取范围之间的所有数字

时间:2015-01-01 06:21:09

标签: sql-server sql-server-2008

我有一张表格如下

Id     RFrom      RTo
....  .......    .....
1       10         14
1       22         25
2       100        102
2       176        180

我希望为每个Id获取每个RFrom和RTo之间的所有数字。我的预期结果如下

Id     NUMS
....  ......
1       10
1       11
1       12
1       13
1       14
1       22
1       23
1       24
1       25
2       100
2       101
2       102
2       176
2       177
2       178
2       179
2       180

我是否必须使用游标来实现这一目标?

3 个答案:

答案 0 :(得分:2)

这是您的示例表

SELECT * INTO #TEMP FROM
(
    SELECT 1 ID, 10 RFROM, 14 RTO
    UNION ALL
    SELECT 1,       22,         25
    UNION ALL
    SELECT 2,       100,        102
    UNION ALL
    SELECT 2,       176,        180
)TAB

您需要为每个Id使用递归才能获得结果

;WITH CTE AS
(
   SELECT ID,RFROM RFROM1,RTO RTO1 
   FROM #TEMP  
   UNION ALL
   SELECT T.ID,RFROM1+1,RTO1 
   FROM #TEMP T
   JOIN CTE ON CTE.ID = T.ID
   WHERE RFROM1 < RTO1
)
SELECT DISTINCT ID,RFROM1 NUMS 
FROM CTE

答案 1 :(得分:1)

另一种选择是使用带有numbers的{​​{1}}表 - 递归可能非常耗时。

创建数字表有几种选择(我建议创建一个永久数据表),但这里是使用common-table-expression创建的临时表:

join

答案 2 :(得分:0)

使用tally table创建stacked CTE,与recursive CTE

相比,效果会更好
declare @min int
select @min= min(RFrom) from yourtable
;WITH e1(n) AS
(
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
), -- 10
e2(n) AS (SELECT 1 FROM e1 CROSS JOIN e1 AS b), -- 10*10
e3(n) AS (SELECT 1 FROM e1 CROSS JOIN e2) -- 10*100
SELECT b.id,
       a.n
FROM   yourtable b
       JOIN (SELECT n = Row_number()OVER (ORDER BY n)+ @min-1
             FROM   e3)a
         ON a.n BETWEEN b.RFrom AND b.RTo
ORDER  BY n; 

检查here以获取信息