使用旧版本的 MYSQL

问题描述

MysqL(旧版本)中是否有一种很好的方法来复制 sql Server 函数 ROW_NUMBER()?

我正在尝试使用此查询找到 2 个最常用的类别及其每天的使用次数,但 ROW_NUMBER 和 PARTITION 在我的旧版 sql 中不可用。

Select a.* 
FROM
( SELECT 
     dDay,category,COUNT(*) as CountOfCategory,ROW_NUMBER() OVER (PARTITION BY dDay ORDER BY COUNT(*) DESC) AS intRow
  FROM Table1
  GROUP BY category,dDate ) as a
WHERE intRow <= 2
ORDER BY dDay,intRow;

这个问题 here一个变体,但我查询中的 COUNT(*) 似乎不适合那里的解决方案。

输入

dDay 类别
1 汽车
2 自行车
2 汽车
1 汽车
3 卡车
1 自行车
1 汽车
3 汽车
3 汽车
2 自行车
1 自行车
2 卡车
2 卡车
2 卡车

预期输出:每天前 2 个类别(及其总数)

dDay 类别 CountOfCategory
1 汽车 3
1 自行车 2
2 自行车 2
2 卡车 2
3 汽车 2
3 卡车 1

解决方法

我正在尝试使用此查询找到 2 个最常用的类别及其每天的使用次数,但 ROW_NUMBER 和 PARTITION 在我的旧版 SQL 中不可用。

在旧版本的 MySQL 中,我认为最简单的解决方案是将类别放在一个列中,使用两级聚合:

SELECT dDay,SUBSTRING_INDEX(GROUP_CONCAT(category,':',CountOfCategory ORDER BY CountOfCategory DESC),',2)
FROM (SELECT dDay,category,COUNT(*) as CountOfCategory,FROM Table1
      GROUP BY category,dDate
     ) cd
GROUP BY dDay;

希望这足够了,直到您能够升级到更现代的 MySQL 版本。

编辑:

您实际上可以使用变量来做您想做的事:

SELECT cd.*
FROM (SELECT cd.*,(@rn := if(@d = dDay,@rn + 1,if(@d := dDay,1,1)
                       )
             ) as rn
      FROM (SELECT dDay,FROM Table1
            GROUP BY category,dDate
            ORDER BY dDate,COUNT(*) DESC
           ) cd CROSS JOIN
           (SELECT @d := -1,@rn := 0) params
      ) cd
WHERE rn <= 2
ORDER BY dDate,rn;