【问题标题】:Identify ranges of integers and group them by their start and end points识别整数范围并按它们的起点和终点对它们进行分组
【发布时间】:2018-01-20 13:31:21
【问题描述】:

假设我有一个包含一列 (IDNUMBER) 的数据集,如下所示:

IDNUMBER
1
2
3
1001
1002
1003
1004
1005

理想情况下,我希望将此列中存在的任何数据分成代表连续值范围的两列。

START, END
1, 3
1001, 1005

我可以使用光标或循环来执行此操作,但是否有基于集合的解决方案?

谢谢。

【问题讨论】:

    标签: sql sql-server tsql aggregate-functions


    【解决方案1】:

    这是一个经典的峡岛

    示例

    Select [Start] = min(IDNUMBER)
          ,[End]   = max(IDNUMBER)
     From (    
            Select *
                  ,Grp = IDNUMBER - Row_Number() over (Order by IDNUMBER)
             from YourTable
          ) A
     Group By Grp
    

    退货

    Start   End
    1       3
    1001    1005
    

    为了帮助您可视化这一点,子查询生成以下内容

    【讨论】:

    • 非常好。感谢您的帮助。
    • 你只领先我几分钟。我的代码中的答案几乎是一样的,但我没有给出答案,因为我详细阐述了这个概念背后的原因。赞一个。
    【解决方案2】:

    您需要的是一个随每条记录递增 1 的数字。 ROW_NUMBER() OVER 应该可以工作。这样,您将从这个递增的数字中减去您的 IDNUMBER。随着 IDNUMBER 增加 1,ROWNUMBER 也增加。因此,只要分组中没有中断,结果DataGroup 将等于相同的整数。

    因此,您使用该值进行子查询,并且您现在拥有一个唯一的组 ID,可以方便地进行分组。

    SELECT MIN(IDNUMBER), MAX(IDNUMBER) 
    FROM (SELECT IDNUMBER, IDNUMBER - ROW_NUMBER() OVER (ORDER BY IDNUMBER) AS DataGroup FROM MyTable)
    GROUP BY DataGroup
    ORDER BY DataGroup
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-26
      • 1970-01-01
      相关资源
      最近更新 更多