This question uses MySQL 8.0 and has not been tested in MySQL 5.6, so it is not guaranteed to be correct.
topic
Topic source: The flow of people in the
Find out three or more good records with the number of people in each row greater than 100
and id
create table stadium (
id int,
visit_date date,
people int
)
insert into stadium values
(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-09', 188);
SQL: Method 1
select * from (
select *, count(*) over(partition by diff) as counts from (
select *, id - row_number() over(order by id) as diff from stadium
where people >= 100
) as base
) as s where counts >= 3;
Parse
The crux of the problem is how to know which days of id
are consecutive.
The method used here is to first filter out peope
greater than or equal to 100
, then rank the data, and then id
. If the difference between them is the same, it means that those days are consecutive.
Specific steps:
- First filter out the data
people
greater than or equal to100
- Calculate the rank using
row_number()
versusid
- With
id
subtracting the rank is calculatedid
the difference between and the position (as a temporary tablebase
) For
base
query and followdiff
group, namedcounts
(as a temporary tables
)- Using
over(partition by diff)
here is more accurategroup by
Becausegroup by
needs to correspond one-to-oneselect
- Using
- Query the
s
table and filter out the datacounts
greater than or equal to3
SQL: Method 2
select * from (
select *, (id - (@rrk:=@rrk + 1)) as diff
from stadium, (select @rrk:=0) as init where people >= 100
) as s1 where diff in (
select diff from (
select (id - (@rk:=@rk + 1)) as diff
from stadium, (select @rk:=0) as init where people >= 100
) as s2 group by diff having count(*) >= 3
);
Parse
The idea is the same as method 1, but the implementation method is different. Here, the grouping group by
, so the steps are a little more complicated than the method of partition by
- First filter out the data
people
greater than or equal to100
- Then use the variable to calculate
diff
(you can also userow_number()
) as a temporary tables1
. - Query the
s1
table to filter out the data we want - Here we think that if there is a
diff
, we can filterin
- This step is to repeat the above
diff
, and then use it as a temporary tables2
. Here also the outside layer query packet
diff
, isselect diff from s2
, usinggroup by
ofdiff
group, and withhaving
screened greater than or equal3
ofdiff
group by
needs to be inselect
fields. If this query is not made,group by
will be problems with using 061f3c5b04635a.
- Query the
s1
table and use thein
operator to find the data.
Tips
Cannot use two same variables in one SQL
More reference for solving problems: https://github.com/astak16/blog-mysql
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。