生成两个数字之间的数字范围

时间:2017-05-17 04:16:25

标签: sql sql-server tsql

我可以使用查询的一些帮助来扩展我正在使用的CSV,但我不知道处理查询的最佳方法。我的数据如下:

ID-Begin | ID-End | Color | Dwelling
-------------------------------------
79000    | 79999  | Red   | Condo
82100    | 82600  | Blue  | House
etc

我需要在起始ID和结束ID之间生成一个范围,然后复制该范围的颜色和居住条目。这是我希望实现的目标:

 ID   |  Color  | Dwelling
------------------------
79000 |  Red    | Condo
79001 |  Red    | Condo
79002 |  Red    | Condo
.....
79999 |  Red    | Condo
82100 |  Blue   | House
82101 |  Blue   | House
.....
82600 |  Blue   | House

我已经看到其他方法允许我生成一个数字范围,但没有任何方法可以从表格中的列中提取开始和结束数字。

无论如何,非常感谢帮助!!

风暴

5 个答案:

答案 0 :(得分:5)

试试这个:

declare @content table ([ID-Begin] int,[ID-End] int,Color char(20),Dwelling char(20))
insert into @content values(79000,79999,'Red' ,'Condo')
insert into @content values(82100,82600,'Blue','House')

;with cte as (
    select [ID-Begin] ,[ID-End] ,Color,Dwelling
    from @content
    union all
    select [ID-Begin]+1,[ID-End],Color,Dwelling
    from cte
    where [ID-Begin]+1<=[ID-End]
    )
    select [Id-Begin],Color,Dwelling from cte order by [ID-Begin] 
    option (maxrecursion 10000)

答案 1 :(得分:1)

使用数字或理货表

SELECT n.number as ID, t.Color, t.Dwelling
FROM   yourtable t
       INNER JOIN number_table n ON  n.number >= t.ID_Begin
                                 AND n.number <= t.ID_End

答案 2 :(得分:1)

最简单(也可能是最好)的方法是使用数字表。如果您还没有数字表,请阅读this Stackoverflow post有关如何创建它的信息。如果您想了解更多关于什么是数字表以及为什么需要数字表,请阅读Jeff Moden的this blog post

获得数字表后,您只需使用内部联接:

SELECT Number as Id,
       Color,
       Dwelling
FROM YourTable 
INNER JOIN Numbers ON Number >= [ID-Begin] 
                  AND Number <= [ID-End]

答案 3 :(得分:0)

你可以用这样的递归CTE来做到这一点

;WITH temp AS
(
   SELECT 1 AS ID 
   UNION ALL 
   SELECT t.ID + 1 FROM temp t
   WHERE t.ID < 100000
) -- return table with id from 1 to 100000
SELECT t.ID,  y.Color, y.Dwelling
FROM YourTable y
INNER JOIN temp t ON t.ID BETWEEN y.IdBegin AND y.IdEnd
OPTION (MAXRECURSION 0)

答案 4 :(得分:0)

针对SQL 2017和更高版本的更新:如果您想要的序列为<8k,那么它将起作用:

Declare @start_num int = 1000
,   @end_num int = 1050

Select [number] = @start_num + ROW_NUMBER() over (order by (Select null))
from string_split(replicate(' ',@end_num-@start_num-1),' ')