简体   繁体   English

SQL查询显示连续3行或更多行且人数超过100人的记录

[英]SQL query to display the records which have 3 or more consecutive rows and the amount of people more than 100

I have a table with the following structure:我有一个具有以下结构的表:

+----+------------+--------+
| id | visit_date | people |
+----+------------+--------+
|  1 | 2017-01-01 |     10 |
|  2 | 2017-01-02 |    109 |
|  3 | 2017-01-03 |    150 |
|  4 | 2017-01-04 |     99 |
|  5 | 2017-01-05 |    145 |
|  6 | 2017-01-06 |   1455 |
|  7 | 2017-01-07 |    199 |
|  8 | 2017-01-08 |    188 |
+----+------------+--------+

I need a query to display the records which have 3 or more consecutive rows and the amount of people more than 100. So the output would be:我需要一个查询来显示连续 3 行或更多行且人数超过 100 的记录。所以输出将是:

+----+------------+--------+
| id | visit_date | people |
+----+------------+--------+
|  5 | 2017-01-05 |    145 |
|  6 | 2017-01-06 |   1455 |
|  7 | 2017-01-07 |    199 |
|  8 | 2017-01-08 |     88 |
+----+------------+--------+

Create table statement for convenience:为方便起见,创建表语句:

CREATE TABLE stadium(id INT, visit_date DATE, people INT);
INSERT INTO stadium VALUES(1, '01/JAN/17', 10);
INSERT INTO stadium VALUES(1, '02/JAN/17', 109);
INSERT INTO stadium VALUES(1, '03/JAN/17', 150);
INSERT INTO stadium VALUES(1, '04/JAN/17', 99);
INSERT INTO stadium VALUES(1, '05/JAN/17', 145);
INSERT INTO stadium VALUES(1, '06/JAN/17', 1455);
INSERT INTO stadium VALUES(1, '07/JAN/17', 199);
INSERT INTO stadium VALUES(1, '08/JAN/17', 188);

This is in Oracle SQL这是在 Oracle SQL 中

I would highly obliged if anyone can explain the logic along with solution.如果有人可以解释逻辑和解决方案,我将非常感激。

This is a type of gaps-and-islands problem.这是一种间隙和岛屿问题。 You can use the difference of row numbers to identify the groups.您可以使用行号的差异来识别组。 Then a count(*) to count the rows and filter:然后使用count(*)来计算行数和过滤器:

select s.*
from (select s.*,
             count(*) over (partition by id, seqnum - seqnum_2) as num_in_row
      from (select s.*,
                   row_number() over (partition by id order by visit_date) as seqnum,
                   row_number() over (partition by id, (case when people > 100 then 1 else 0 end) order by visit_date) as seqnum_2
            from stadium s
           ) s
      where people > 100
     ) s
where num_in_row >= 3;

Here is SQL Fiddle.是 SQL 小提琴。

This is a typical pattern matching problem.这是一个典型的模式匹配问题。 match_recognize does quick work of such tasks. match_recognize可以快速完成此类任务。

select id, visit_date, people
from   stadium
match_recognize(
  order by visit_date
  all rows per match
  pattern ( a{3, } )
  define a as people >= 100    --  or > 100?
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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