Leetcode刷SQL 4、体育馆的人流量

X 市建了一个新的体育馆,每日人流量信息被记录在这三列信息中:序号 (id)、日期 (date)、 人流量 (people)。

请编写一个查询语句,找出高峰期时段,要求连续三天及以上,并且每天人流量均不少于100。

例如,表 stadium:

+------+------------+-----------+
| id   | 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       |
+------+------------+-----------+

对于上面的示例数据,输出为:

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

Note:
每天只有一行记录,日期随着 id 的增加而增加。

思路:
这一题同样很简单,和上一题连续数字是非常类似的,首先做一轮查询,记录连续大于100的天数,默认为1,如果下一天符合则+1,否则重置;同时给一个标识,用于标识出当前连续段的特征值。
得到以上结果,我们就可以查出所有连续次数大于等于3的的天数记录及其标识,这样也可以得到需要的结果了。

SELECT
  e.id,
  e.date,
  e.people
FROM
  (SELECT
    id,
    s.date,
    @sdate1 := (
      CASE
        WHEN s.people >= 100
        THEN @sdate1
        ELSE @sdate1 + 1
      END
    ) AS sdate,
    s.people
  FROM
    stadium s,
    (SELECT
      @sdate1 := 0) b) e,
  (SELECT
    c.sdate
  FROM
    (SELECT
      id,
      s.date,
      @sdate := (
        CASE
          WHEN s.people >= 100
          THEN @sdate
          ELSE @sdate + 1
        END
      ) AS sdate,
      s.people
    FROM
      stadium s,
      (SELECT
        @sdate := 0) b) c
  GROUP BY c.sdate
  HAVING COUNT(c.sdate) > 3) d
WHERE d.sdate = e.sdate
  AND e.people >= 100

由于mysql没有with as,这里复用部分的子查询就显得很长很难看了。
我用的方法是比较死板的遍历查找,只能击败88.48%,其他提交的普遍采用以id+1,id+2为条件做全表查询,更巧妙吧。

SELECT DISTINCT
  s1.*
FROM
  stadium AS s1,
  stadium AS s2,
  stadium AS s3
WHERE (
    (s1.id + 1 = s2.id
      AND s1.id + 2 = s3.id)
    OR (s1.id - 1 = s2.id
      AND s1.id + 1 = s3.id)
    OR (s1.id - 2 = s2.id
      AND s1.id - 1 = s3.id)
  )
  AND s1.people >= 100
  AND s2.people >= 100
  AND s3.people >= 100
ORDER BY s1.id

转载于:https://www.cnblogs.com/linux-java/p/9766433.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值