mysql中每个组的前N个Sql问题

mysql中每个组的前N个Sql问题,mysql,sql,database,greatest-n-per-group,Mysql,Sql,Database,Greatest N Per Group,请注意,我在从类似下面所示的数据集中查询每个类别的前N名时遇到问题。我在这方面看到了各种各样的线索,但我很难使他们的查询适应我的具体问题 +----+---------------------------------+-------+ | ID | Prod |Cat Id | +----+---------------------------------+-------+ | 1 | kntrn

请注意,我在从类似下面所示的数据集中查询每个类别的前N名时遇到问题。我在这方面看到了各种各样的线索,但我很难使他们的查询适应我的具体问题

+----+---------------------------------+-------+
| ID | Prod                            |Cat Id |
+----+---------------------------------+-------+
|  1 |  kntrn                          |     1 |
|  2 | kntrn e                         |     1 |
|  3 | e spl                           |     1 |
|  4 | spl php                         |     1 |
|  5 | php cicarredgtal                |     1 |
|  6 | cicarredgtal servecounterstrike |     1 |
|  7 | servecounterstrike com          |     1 |
|  8 |  zlv                            |     2 |
|  9 | zlv enter                       |     2 |
| 10 | spl php                         |     2 |
+----+---------------------------------+-------+
我想根据这条规则进行分组,为每个catid选择前3个产品

请注意,从这个意义上讲,top是所有类别中最高的产品数量


因此,对于上面的示例,spl php对于catID 1来说是最高的,因为它在所有类别中出现两次

这可能不是很漂亮,但我认为它会起作用:

SELECT cat_id, prod, pos FROM (
    SELECT cat_id, pos, prod, if(@last_id = cat_id, @cnt := @cnt + 1, (@cnt := 0 || @last_id := cat_id)) cnt
    FROM (
        SELECT p.cat_id, pseq.cnt pos, pseq.prod
        FROM (
            SELECT prod, count(*) cnt FROM prods GROUP BY prod ORDER BY cnt DESC
        ) pseq
        INNER JOIN prods p ON p.prod = pseq.prod
        ORDER BY cat_id, pseq.cnt DESC
    ) po
) plist
WHERE cnt <= 3;

Based on the above data, this will return:
+--------+-----------+-----+
| cat_id | prod      | pos |
+--------+-----------+-----+
|      1 | spl php   |   2 |
|      1 |  kntrn    |   1 |
|      1 | kntrn e   |   1 |
|      2 | spl php   |   2 |
|      2 |  zlv      |   1 |
|      2 | zlv enter |   1 |
+--------+-----------+-----+

MySQL不支持TOP关键字,您需要使用LIMIT和ORDER BY来获得相同的结果。我理解这一点,但我在为这样的问题生成相关子查询时遇到了问题。限制每个组的结果计数是一件复杂的事情。对每个类别进行多个查询比较容易。是否涉及其他表?一个有类别和产品关系的表?它是我在项目中遇到的一个遗留表,没有类别和产品关系表。顺便说一句,我喜欢这些脑力练习,但我建议将解决方案更多地放在代码中,而不是放在单个MySQL查询中。为什么你认为代码比sql更好。我想,这需要多次访问数据库。根据您的服务器使用情况,通常情况下,对数据库进行多次微小的往返比一次长查询要好。在大型数据集上,此查询的运行速度相当慢。此外,它非常特定于MySQL,如果您想要更改,将很难移植。此查询执行笛卡尔乘法排序,并且不会返回每个类别的前3名。嗯。它在您提供的示例数据集上起作用。另外,我看不出它是如何进行笛卡尔乘法的——我唯一一次将表连接到它本身是在prod的一个不同的事件中——我将基于上面的数据包含查询的输出。