X 市建了一个新的体育馆,每日人流量信息被记录在这三列信息中:序号 (id)、日期 (date)、 人流量(people)。
请编写一个查询语句,找出高峰期时段,要求连续三天及以上,并且每天人流量均不少于100。
例如,表 stadium
image.png

对于上面的示例数据,输出为:
image.png
Note:
每天只有一行记录,日期随着 id 的增加而增加。

答案

  1. select distinct a.*
  2. from stadium a,stadium b,stadium c
  3. where a.people >= 100 and b.people >= 100 and c.people >= 100 and
  4. (
  5. (a.id+1 = b.id and b.id+1 = c.id) or
  6. (a.id-1 = b.id and a.id+1 = c.id) or
  7. (a.id-1 = c.id and a.id+1 = b.id) or
  8. (a.id-2 = b.id and a.id-1 = c.id) or
  9. (a.id-1 = b.id and a.id-2 = c.id)
  10. )
  11. order by a.id

笔记

高票答案与我的逻辑一样,但如果需要连续 n 天,没办法灵活改动。
有别人的写法:

  1. SELECT id, `date`, people
  2. FROM (
  3. SELECT id, `date`, people, @m := IF(k >= 3 OR (@n - k >= 0 AND k > 0), 1, 0) AS t, @n := IF(k = 3, 3, @n - k) AS _2, k
  4. FROM (
  5. SELECT id, `date`, people,
  6. @i := IF(people >= 100, 1, 0) AS _,
  7. @j := IF(@i = 1, @j + 1, 0) AS k
  8. FROM stadium , (SELECT @i:=0, @j:=0) __a
  9. ORDER BY id
  10. ) t , (SELECT @m:=0, @n:=0) __a
  11. ORDER BY id DESC
  12. ) a WHERE t = 1
  13. ORDER BY id
  1. 可以解决十几天连续超过100人的问题; 引入单个变量; 代码可读性和可迁移性也还行
  2. select stadium.* from stadium
  3. inner join
  4. (
  5. select
  6. id-rownum as diff
  7. ,group_concat(id) as idlist
  8. from
  9. (
  10. select
  11. @rownum:=@rownum+1 as rownum
  12. ,id
  13. from stadium,(select @rownum :=0) t
  14. where people>=100
  15. )t
  16. group by id-rownum
  17. having length(group_concat(id))-length(replace(group_concat(id),',',''))>=2 #表示至少出现三个id
  18. )t
  19. on find_in_set(stadium.id,t.idlist)