简体   繁体   English

如何使用 MySQL 获得 select 连续组数的最大值和最小值?

[英]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 .在这里,用户想查看某个sectionstudent_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM