Mysql限制每组奇怪的结果行数

标签 mysql group-by having having-clause

我想为每个 symbolid 获取最新的 4 个日期。我修改了代码 here如下:

set @num := 0, @symbolid := '';
select symbolid, date,
@num := if(@symbolid = symbolid, @num + 1, 1) as row_number,
@symbolid := symbolid as dummy
from projections
group by symbolid, date desc
having row_number < 5

得到如下结果:

symbolid                date   row_number   dummy       
1       '2011-09-01 00:00:00'       1       1
1       '2011-08-31 00:00:00'       3       1
1       '2011-08-30 00:00:00'       5       1
2       '2011-09-01 00:00:00'       1       2
2       '2011-08-31 00:00:00'       3       2
2       '2011-08-30 00:00:00'       5       2
3       '2011-09-01 00:00:00'       1       3
3       '2011-08-31 00:00:00'       3       3
3       '2011-08-30 00:00:00'       5       3
4       '2011-09-01 00:00:00'       1       4
...

明显的问题是,为什么每个 symbolid 我只得到 3 行,为什么它们编号为 1、3、5?一些细节:

  1. 我尝试了强制索引和不强制索引(如此处所示),两种方式都得到了相同的结果。
  2. 日期正确,即列表正确显示每个 symbolid 的前 3 个日期,但 row_number 值关闭
  3. 当我不使用“having”语句时,行号是正确的,即最近的日期是 1,下一个最近的日期是 2,依此类推

显然 row_number 计算字段受到“having”子句的影响,但我不知道如何修复它。

我意识到我可以将“having”更改为“having row_number < 7”(6 与 5 相同),但它非常丑陋,我想知道如何让它“表现”。

最佳答案

我不是 100% 确定它为什么会这样(也许是因为逻辑上 SELECTORDER BY 之前被处理),但它应该按预期工作:

SELECT * 
FROM 
(
    select symbolid, date,
    @num := if(@symbolid = symbolid, @num + 1, 1) as row_number,
    @symbolid := symbolid as dummy
    from projections
    INNER JOIN (SELECT @symbolid:=0)c
    INNER JOIN (SELECT @num:=0)d
    group by symbolid, date desc

) a
WHERE row_number < 5

关于Mysql限制每组奇怪的结果行数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7285901/

相关文章:

sql - 将 SQL 查询转换为 Doctrine2 DQL

MySQL 更新子集

mysql - 在 MySQL 中将 HAVING 与 CASE 或分析函数混合(PartitionQualify(?

mysql - 关于与多个表(数据库)的关联

php - 如何在数据库中存储多组值?

php - 了解 url 缩短函数

mysql - SQL `GROUP BY` 和 `MAX()`

MySQL 避免来自不同表的 GROUP BY 列

mysql - 计算字段中的 Have 查询速度慢

javascript - 从日期选择器按天搜索