根据不同的ID范围创建一组ID

时间:2016-06-15 21:46:14

标签: sql sql-server tsql

我有一组缺少文档ID范围的表。 Start Range是开始ID,End Range是结束ID,Missing是该范围内缺少的行数(包括其计数中的开始和结束ID) )。我想知道如何解析单个ID而不是基于Missing列的实际范围。

这是数据的呈现方式:

+-------------+-----------+---------+-----------+
| Start Range | End Range | Missing | Date      |
+-------------+-----------+---------+-----------+
| 184         | 186       | 3       | 1/9/1979  |
| 204         | 207       | 4       | 1/9/1979  |
| 209         | 212       | 4       | 1/9/1979  |
| 223         | 224       | 2       | 1/9/1979  |
| 240         | 241       | 2       | 1/10/1979 |
| 243         | 243       | 1       | 1/10/1979 |
| 248         | 249       | 2       | 1/10/1979 |
| 261         | 265       | 5       | 1/11/1979 |
+-------------+-----------+---------+-----------+

我希望能够实现输出:

+-----+-----------+
| ID  | Date      |
+-----+-----------+
| 184 | 1/9/1979  |
| 185 | 1/9/1979 |
| 186 | 1/9/1979 |
| 204 | 1/9/1979 |
| 205 | 1/9/1979 |
| 206 | 1/9/1979 |
| 207 | 1/9/1979 |
| 209 | 1/9/1979 |
| 210 | 1/9/1979 |
| 211 | 1/9/1979 |
| 212 | 1/9/1979 |
| 223 | 1/9/1979 |
| 224 | 1/9/1979 |
| 240 | 1/10/1979 |
| 241 | 1/10/1979 |
| 243 | 1/10/1979 |
| 248 | 1/10/1979 |
| 249 | 1/10/1979 |
| 261 | 1/11/1979 |
| 262 | 1/11/1979 |
| 263 | 1/11/1979 |
| 264 | 1/11/1979 |
| 265 | 1/11/1979 |
+-----+-----------+

实现这一目标的最佳方法是什么?谢谢你的帮助。

2 个答案:

答案 0 :(得分:2)

我使用UDF生成范围,但是数字表或计数表也可以实现这个技巧

Declare @Table table (StartRange int,EndRange int,Date Date)
Insert into @Table values
(184,186,'1979-01-09'),
(204,207,'1979-01-09')


Select B.ID
      ,A.Date
 From @Table A
 Join (Select ID=cast(RetVal as int) from [dbo].[udf-Create-Range-Number](1,9999,1)) B
   on B.ID between A.StartRange and A.EndRange
 Order by B.ID,Date

返回

ID  Date
184 1979-01-09
185 1979-01-09
186 1979-01-09
204 1979-01-09
205 1979-01-09
206 1979-01-09
207 1979-01-09

UDF

CREATE FUNCTION [dbo].[udf-Create-Range-Number] (@R1 money,@R2 money,@Incr money)

-- Syntax Select * from [dbo].[udf-Create-Range-Number](0,100,2)

Returns 
@ReturnVal Table (RetVal money)

As
Begin
    With NumbTable as (
        Select NumbFrom = @R1
        union all
        Select nf.NumbFrom + @Incr
        From NumbTable nf
        Where nf.NumbFrom < @R2
    )
    Insert into @ReturnVal(RetVal)

    Select NumbFrom from NumbTable Option (maxrecursion 32767)

    Return
End

答案 1 :(得分:1)

构建计数表或CTE。 tally table

这只是一列递增整数n

Select tally.n as Id,  missingRange.date
from tally
 inner join missingRange
On tally.n >= beginRange 
And tally.n <= endRange