【问题标题】:SQL GROUP BY: intervals in continuity?SQL GROUP BY:连续的间隔?
【发布时间】:2012-03-20 12:47:19
【问题描述】:

这个想法是说你有下表。

-------------
| oID | Area|
-------------
| 1 | 5     |
| 2 | 2     |
| 3 | 3     |
| 5 | 3     |
| 6 | 4     |
| 7 | 5     |
-------------

如果可以按连续性分组,则此伪查询

SELECT SUM(Area) FROM sample_table GROUP BY CONTINUITY(oID)

会返回

-------------
| SUM(Area) |
-------------
|  10       |
|  12       |
-------------

在 oID 处出现连续性中断的情况下,或更确切地说是缺少表示 oID 4 的条目。

Sql 的标准函数中是否存在这样的功能?

【问题讨论】:

    标签: mysql sql gaps-and-islands


    【解决方案1】:

    “SQL的标准函数”中没有这样的功能,但是通过一些技巧可以得到想要的结果集。

    通过下图所示的子查询,我们创建了一个虚拟字段,您可以在外部查询中将其用于GROUP BY。每次oID序列中出现间隙时,该虚拟字段的值就会增加。这样我们就可以为每个“数据孤岛”创建一个标识符:

    SELECT  SUM(Area), COUNT(*) AS Count_Rows
    FROM    (
            /* @group_enumerator is incremented each time there is a gap in oIDs continuity */
            SELECT  @group_enumerator := @group_enumerator + (@prev_oID != oID - 1) AS group_enumerator,
                    @prev_oID := oID AS prev_oID,
                    sample_table.*
            FROM    (
                    SELECT  @group_enumerator := 0,
                            @prev_oID := -1
                    ) vars,
                    sample_table
            /* correct order is very important */
            ORDER BY
                    oID
            ) q
    GROUP BY
            group_enumerator
    

    测试表和数据生成:

    CREATE TABLE sample_table (oID INT auto_increment, Area INT, PRIMARY KEY(oID));
    INSERT INTO sample_table (oID, Area) VALUES (1,5), (2,2), (3,3), (5,3), (6,4), (7,5);
    

    我要感谢 Quassnoi 指出 this trick in my related question ;-)

    更新:在示例查询中添加了测试表和数据并修复了重复的列名。

    【讨论】:

      【解决方案2】:

      这是一篇博文,提供了与grouping by contiguous data 相关的非常详尽的解释和示例。如果您在理解或实施方面有任何问题,我可以尝试为您的问题提供实施。

      【讨论】:

      • 不使用临时表也可以。
      猜你喜欢
      • 2012-10-12
      • 1970-01-01
      • 1970-01-01
      • 2010-11-11
      • 1970-01-01
      • 2021-11-20
      • 1970-01-01
      • 2011-02-07
      • 1970-01-01
      相关资源
      最近更新 更多