Mysql SQL中有查询序列的习惯用法吗?

Mysql SQL中有查询序列的习惯用法吗?,mysql,sql,count,window-functions,gaps-and-islands,Mysql,Sql,Count,Window Functions,Gaps And Islands,我正在学习面试一份涉及很多SQL语言的工作。我注意到有一些练习是围绕着基于跨行序列返回值展开的,我很想知道是否有一种标准的方法来实现这一点。类似于下面的子查询,我发现它对于选择最大/最小值非常有用: ( SELECT column FROM table ... ORDER BY column [DESC] LIMIT 1 ) 以下是一个相关的例子: 此表的每一行都包含参观日期和体育场的参观id以及参观期间的人数。 没有两行具有相同的就诊日期,并且随着id的增加,日期也会增加 编写SQL查询以显

我正在学习面试一份涉及很多SQL语言的工作。我注意到有一些练习是围绕着基于跨行序列返回值展开的,我很想知道是否有一种标准的方法来实现这一点。类似于下面的子查询,我发现它对于选择最大/最小值非常有用:

( SELECT column FROM table ... ORDER BY column [DESC] LIMIT 1 )
以下是一个相关的例子:

此表的每一行都包含参观日期和体育场的参观id以及参观期间的人数。 没有两行具有相同的就诊日期,并且随着id的增加,日期也会增加

编写SQL查询以显示具有连续id的三行或更多行的记录,并且每个行的人数大于或等于100

按访问日期以升序返回结果表

查询结果格式如下例所示

Stadium table:
+------+------------+-----------+
| 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-09 | 188       |
+------+------------+-----------+

Result table:
+------+------------+-----------+
| id   | visit_date | people    |
+------+------------+-----------+
| 5    | 2017-01-05 | 145       |
| 6    | 2017-01-06 | 1455      |
| 7    | 2017-01-07 | 199       |
| 8    | 2017-01-09 | 188       |
+------+------------+-----------+
我试图解决这个问题时使用了一个用户变量。下面的代码是我找到解决方案的最佳途径:

SET @rowIndex = 0;

SELECT s1.id, s1.visit_date, s1.people
FROM ( SELECT @rowIndex:=@rowIndex+1 as rowIndex, s.id, s.visit_date, s.people
    FROM Stadium as s
    WHERE s.people >=100 ) as s1
GROUP BY rowIndex - s1.id, s1.id, s1.visit_date, s1.people
HAVING COUNT(s.id) >= 3
ORDER BY s1.visit_date
上面的查询某处有语法错误。消息:

您的SQL语法有错误;检查手册 对应于您的MySQL服务器版本,以便使用正确的语法 在“选择s1.id、s1.visit\U日期、s1.PEOPLES FROM”附近(选择@rowIndex :=@rowIndex+1 as'在第4行


是否有人喜欢使用基于序列的行选择方法?也许不太重要的是,有人能在我上面的查询中发现错误吗?

我将把这看作是一个间隙和孤岛问题。下面是一种使用窗口函数的方法:

select id, visit_date, people
from (
    select s.*, count(*) over(partition by id - rn) cnt
    from (
        select s.*, row_number() over(order by id) rn
        from stadium s
        where people > 100
    ) s
) s
where cnt >= 3

我们的想法是过滤掉少于100次访问的天数,然后使用
id
和单调递增的等级之间的差异来识别岛屿(连续天数超过100次访问)。然后,我们可以保留只有3行以上的组。

s1.id
s1之间缺少逗号。请访问组中的\u date
。@jarlh谢谢,这是一个。编辑以反映。我再次运行了它,看起来查询中仍然存在错误。非常感谢您的任何想法!看起来这很有用。我有一个问题n关于(…)上的计数(*)-我想我试图通过在HAVING语句中使用COUNT()来实现相同的函数。我的推理是,作为一个窗口函数,COUNT()将返回相关窗口的计数,导致HAVING语句删除计数小于3的窗口。你认为这是正确的吗?
select id, visit_date, people
from (
    select s.*, count(*) over(partition by id - rn) cnt
    from (
        select s.*, row_number() over(order by id) rn
        from stadium s
        where people > 100
    ) s
) s
where cnt >= 3