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

时间:2011-08-20 17:55:01

标签: mysql sql database greatest-n-per-group

请问我从类似下图所示的数据集中查询每个类别的前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 |
+----+---------------------------------+-------+

我想根据这条规则进行分组(1)为每个catid选择Top 3 Prod。

请注意,这个意义上的顶部是所有类别中最高的刺激数。

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

1 个答案:

答案 0 :(得分: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 |
+--------+-----------+-----+