SQL:从各个起点创建数字的顺序列表

时间:2012-10-06 19:01:24

标签: sql range sequence sequential gaps-and-islands

我坚持这个SQL问题。

我有一个列是一个起点列表(prevdoc),另一个列列出了起点(exdiff)后我需要多少个序列号。

例如,以下是前几行:

prevdoc | exdiff
----------------    
1       | 3
21      | 2
126     | 2

所以我需要输出看起来像:

2
3
4
22
23
127
128

我甚至迷失在哪里开始。任何人都可以告诉我这个解决方案的SQL代码吗?

谢谢!

3 个答案:

答案 0 :(得分:1)

;with a as
(
select prevdoc + 1 col, exdiff
from <table> where exdiff > 0
union all
select col + 1, exdiff - 1
from a
where exdiff > 1
)
select col

答案 1 :(得分:1)

如果您的exdiff是一个小数字,您可以使用此处所示的SELECT..UNION ALL组成一个虚拟的数字表格并加入其中:

select prevdoc+number
from doc
join (select 1 number union all
      select 2 union all
      select 3 union all
      select 4 union all
      select 5) x on x.number <= doc.exdiff
order by 1;

我已提供5但您可以根据需要进行扩展。您尚未指定DBMS,但在每个DBMS中都会有一个序列号源,例如在SQL Server中,您可以使用:

select prevdoc+number
from doc
join master..spt_values v on
   v.number <= doc.exdiff and
   v.number >= 1 and
   v.type = 'p'
order by 1;

master..spt_values表包含0-2047之间的数字(按类型='p'过滤时)。

答案 2 :(得分:0)

如果数字不是太大,那么您可以在大多数数据库中使用以下技巧:

select t.exdiff + seqnum
from t join
     (select row_number() over (order by column_name) as seqnum
      from INFORMATION_SCHEMA.columns
     ) nums
     on t.exdiff <= seqnum

在子查询中使用INFORMATION_SCHEMA列是任意的。唯一的目的是生成一个至少与最大exdiff数一样长的数字序列。

此方法适用于支持排名功能的任何数据库。大多数数据库都有一种特定于数据库的生成序列的方式(例如SQL Server中的递归CTE和Oracle中的CONNECT BY)。