CBu*_*Bus 6 mysql sql gaps-and-islands
这个想法就是说你有下表.
-------------
| oID | Area|
-------------
| 1 | 5 |
| 2 | 2 |
| 3 | 3 |
| 5 | 3 |
| 6 | 4 |
| 7 | 5 |
-------------
Run Code Online (Sandbox Code Playgroud)
如果按连续性分组,则可以使用此伪查询
SELECT SUM(Area) FROM sample_table GROUP BY CONTINUITY(oID)
Run Code Online (Sandbox Code Playgroud)
会回来的
-------------
| SUM(Area) |
-------------
| 10 |
| 12 |
-------------
Run Code Online (Sandbox Code Playgroud)
如果在oID处出现连续性中断,或者缺少连续性中断,则表示oID 4.
这些功能是否存在于Sql的标准功能中?
"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
Run Code Online (Sandbox Code Playgroud)
测试表和数据生成:
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);
Run Code Online (Sandbox Code Playgroud)
我要感谢Quassnoi 在我的相关问题中指出这个技巧 ;-)
更新:在示例查询中添加了测试表和数据以及修复的重复列名称.
| 归档时间: |
|
| 查看次数: |
992 次 |
| 最近记录: |