[英]How to select maximum and minimum of continuous group numbers using MySQL?
I have a table with some rows, here is the table and row construction queries:我有一个包含一些行的表,这里是表和行构造查询:
create table class_room(
section varchar(20),
section_name varchar(20),
section_id varchar(20),
student_rollno varchar(20)
);
insert into class_room values ('A','DIV A','01','547');
insert into class_room values ('A','DIV A','01','548');
insert into class_room values ('A','DIV A','01','549');
insert into class_room values ('A','DIV A','01','550');
insert into class_room values ('A','DIV A','01','551');
insert into class_room values ('A','DIV A','01','552');
insert into class_room values ('A','DIV A','01','567');
insert into class_room values ('A','DIV A','01','568');
insert into class_room values ('A','DIV A','01','593');
insert into class_room values ('A','DIV A','01','594');
insert into class_room values ('A','DIV A','01','595');
insert into class_room values ('A','DIV A','01','596');
insert into class_room values ('A','DIV A','01','597');
insert into class_room values ('A','DIV A','01','598');
Here user wants to see the ranges of student_rollno
for certain section
.在这里,用户想查看某个section
的student_rollno
范围。 So I have tried the below code:所以我尝试了以下代码:
select section,section_name,section_id,
concat_ws('-',min(student_rollno),max(student_rollno)) as rollno_range
from class_room
where section='A'
group by section_id
having count(*)>=1;
The above code give me this result:上面的代码给了我这个结果:
+---------+--------------+------------+--------------+
| section | section_name | section_id | rollno_range |
+---------+--------------+------------+--------------+
| A | DIV A | 01 | 547-598 |
+---------+--------------+------------+--------------+
But user wants to see the discrete values, which will looks like below solution:但是用户想要查看离散值,这将类似于以下解决方案:
+---------+--------------+------------+--------------------------------+
| section | section_name | section_id | rollno_range |
+---------+--------------+------------+--------------------------------+
| A | DIV A | 01 | 547-552, 567-568, 593-598 |
+---------+--------------+------------+--------------------------------+
I couldn't understand how to get output in above mentioned fashion.我无法理解如何以上述方式获得 output。 Please help.请帮忙。
This is a type of gaps-and-islands problem.这是一种差距和孤岛问题。 You can get adjacent values with no gaps by subtracting a sequence number from the roll no:您可以通过从卷号中减去一个序列号来获得没有间隙的相邻值:
select section, section_name, section_id, min(student_rollno), max(student_rollno)
from (select cr.*,
row_number() over (partition by section, section_name, section_id order by student_rollno) as seqnum
from class_room cr
) cr
group by section, section_name, section_id, (student_rollno - seqnum);
Then you can aggregate this again:然后你可以再次聚合它:
select section, section_name, section_id,
group_concat(min_sr, '-', max_sr order by min_sr separator ', ')
from (select section, section_name, section_id,
min(student_rollno) as min_sr, max(student_rollno) as max_sr
from (select cr.*,
row_number() over (partition by section, section_name, section_id order by student_rollno) as seqnum
from class_room cr
) cr
group by section, section_name, section_id, (student_rollno - seqnum)
) ss
group by section, section_name, section_id;
Here is a db<>fiddle. 这是一个 db<>fiddle。
In older versions of MySQL, you can emulate this using variables.在旧版本的 MySQL 中,您可以使用变量来模拟这一点。 This should work under most circumstances:这应该在大多数情况下工作:
select section, section_name, section_id,
group_concat(min_sr, '-', max_sr order by min_sr separator ', ')
from (select section, section_name, section_id,
min(student_rollno) as min_sr, max(student_rollno) as max_sr
from (select cr.*, (@rn := @rn + 1) as seqnum
from (select cr.*
from class_room cr
order by section, section_name, section_id, student_rollno
) cr cross join
(select @rn := 0) params
) cr
group by section, section_name, section_id, (student_rollno - seqnum)
) ss
group by section, section_name, section_id;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.