Zby*_*nek 6 mysql group-by gaps-and-islands
我有一个具有以下结构的表:
CREATE TABLE `Rings` (
ID_RingType CHAR(2),
Number MEDIUMINT UNSIGNED,
ID_User INT(11)
);
Run Code Online (Sandbox Code Playgroud)
和数据:
INSERT INTO `Rings` VALUES
('AA',1,1),
('AA',2,1),
('AA',3,1),
('AA',11,1),
('AA',12,1),
('AA',13,1),
('AA',14,1),
('AA',15,1),
('AB',16,1),
('AB',17,1),
('AB',18,1),
('AB',19,1),
('AB',20,2),
('AB',21,2),
('AB',22,2);
Run Code Online (Sandbox Code Playgroud)
我想组基于所述数据ID_User
和ID_RingType
和用于数字的每个连续范围列出MIN和MAX。
结果应如下所示:
ID_User | ID_RingType | MIN | MAX
1 | 'AA' | 1 | 3
1 | 'AA' | 11 | 15
1 | 'AB' | 16 | 19
2 | 'AB' | 20 | 22
Run Code Online (Sandbox Code Playgroud)
我浏览了关于这个主题的几篇文章,但无法调整它们以适合我的数据。
任何帮助,将不胜感激。
由于 MySQL 不支持ROW_NUMBER()
,您可以使用变量来创建这样的组。
样本数据
CREATE TABLE `Rings` (
ID_RingType CHAR(2),
Number MEDIUMINT UNSIGNED,
ID_User INT(11)
);
INSERT INTO `Rings` VALUES
('AA',1,1),
('AA',2,1),
('AA',3,1),
('AA',11,1),
('AA',12,1),
('AA',13,1),
('AA',14,1),
('AA',15,1),
('AB',16,1),
('AB',17,1),
('AB',18,1),
('AB',19,1),
('AB',20,2),
('AB',21,2),
('AB',22,2);
Run Code Online (Sandbox Code Playgroud)
询问
SET @grp = 0;
SET @preNum = 0;
SELECT ID_User,ID_RingType,MIN(Number),MAX(Number) FROM
(
SELECT
ID_RingType,
ID_User,
Number,
@grp := CASE WHEN Number = @preNum + 1 THEN @grp ELSE @grp + 1 END grp,
@preNum := Number
FROM `Rings`
ORDER BY ID_RingType,ID_User,Number
)T
GROUP BY ID_RingType,ID_User,grp
Run Code Online (Sandbox Code Playgroud)
输出
ID_User | ID_RingType | MIN | MAX
1 | 'AA' | 1 | 3
1 | 'AA' | 11 | 15
1 | 'AB' | 16 | 19
2 | 'AB' | 20 | 22
Run Code Online (Sandbox Code Playgroud)
变量的答案会更有效,但这里是纯 SQL 的答案:
select
a.id_user,
a.id_ringtype,
a.number as min,
min(b.number) as max
from
rings as a
join rings as b
on a.id_user = b.id_user
and a.id_ringtype = b.id_ringtype
and a.number <= b.number
where not exists
( select 1
from rings as c
where c.id_user = a.id_user
and c.id_ringtype = a.id_ringtype
and c.number = a.number - 1
)
and not exists
( select 1
from rings as d
where d.id_user = b.id_user
and d.id_ringtype = b.id_ringtype
and d.number = b.number + 1
)
group by
a.id_user,
a.id_ringtype,
a.number ;
Run Code Online (Sandbox Code Playgroud)
效率将取决于许多因素(主要是数据的分布),但索引(id_user, id_ringtype, number)
对于此查询至关重要。
归档时间: |
|
查看次数: |
1277 次 |
最近记录: |