【问题标题】:SQL: create sequential list of numbers from various starting pointsSQL:从各个起点创建数字的顺序列表
【发布时间】:2012-10-06 19:01:23
【问题描述】:

我被这个 SQL 问题困住了。

我有一列是起点列表 (prevdoc),还有一列是在起点之后需要多少个序号 (exdiff)。

例如,这里是前几行:

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

所以我需要一个看起来像这样的输出:

2
3
4
22
23
127
128

我什至不知道从哪里开始。谁能告诉我这个解决方案的 SQL 代码?

谢谢!

【问题讨论】:

  • 如果1是起点,为什么输出从2开始?
  • 好问题。我非常感兴趣人们能想出什么。 SQL 对集合(即整数集合)进行操作,因此人们会假设存在比 Gordon 提出的更简单的解决方案。
  • @EvilTeach:我认为这一点回答了你的问题:'列列出了我在之后需要多少个序列号(exdiff)'(重点是我的)。

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


【解决方案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

【讨论】:

    【解决方案2】:

    如果您的 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 之间的数字(按 type='p' 过滤时)。

    【讨论】:

      【解决方案3】:

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

      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)。

      【讨论】:

      • 您不能在子选择中引用prevdoc,因为子选择无法检测到表c。交叉应用在这里看起来很乱。所以我最喜欢引用 new_id() 或现有列之一。
      • “大多数数据库都有一种特定于数据库的生成序列的方式” 还有 PostgreSQL 中隐秘命名的 generate_series() 函数。
      • 对不起,我知道你说这是任意的,但我对 information_schema.columns 感到困惑。那是什么,我该如何使用它?
      猜你喜欢
      • 1970-01-01
      • 2010-11-29
      • 2019-10-20
      • 1970-01-01
      • 2021-07-03
      • 2022-06-24
      • 1970-01-01
      • 2023-01-24
      • 1970-01-01
      相关资源
      最近更新 更多