MySQL返回前n行并将其余行分组

时间:2013-05-07 01:39:24

标签: mysql group-by

我想用MySQL数据绘制饼图。我需要检索前n行并将其余部分分组 问题是第一个查询已经分组了。

SELECT name AS especie, SUM(superficie) AS superficie
FROM ciclos
JOIN cultivos ON id_cultivo = idcultivo
JOIN tbl_especies ON id_especie = idespecie
WHERE fecha_cierre IS NULL
GROUP BY id_especie
ORDER BY superficie DESC

这就是我得到的:

+------------+------------+
|  Especie   | Superficie |
+------------+------------+
| Avena      | 50.0000    |
| Centeno    | 32.4000    |
| Trigo      | 18.0000    |
| Almendros  | 5.1100     |
| Olivos     | 4.7000     |
| Vid        | 1.8300     |
| Nogal      | 0.3500     |
| Cerezo     | 0.2500     |
+------------+------------+

这就是我需要的:

+------------+------------+
|  Especie   | Superficie |
+------------+------------+
| Avena      | 50.0000    |
| Centeno    | 32.4000    |
| Trigo      | 18.0000    |
| Almendros  | 5.1100     |
| Rest       | 7.1300     |
+------------+------------+

在这种情况下,我需要检索前4行并将其余部分分组。

有没有办法用一个查询解决这个问题?

2 个答案:

答案 0 :(得分:0)

您可以使用一个查询执行此操作,但它需要一个子查询(最后,不知何故,您必须对已经分组的数据进行分组)。这是一种特定于MySQL的方法。它使用变量在行上添加序列号,然后将其用于分组:

select (case when rn <= 4 then especie else 'otros' end) as grouping,
       sum(superficie) as superficie
from (SELECT name AS especie, SUM(superficie) AS superficie, @rn := @rn + 1 as rn
      FROM ciclos
      JOIN cultivos ON id_cultivo = idcultivo
      JOIN tbl_especies ON id_especie = idespecie
      cross join (select @rn := 0) const
      WHERE fecha_cierre IS NULL
      GROUP BY id_especie
      ORDER BY superficie DESC
     ) t
group by (case when rn <= 4 then especie else 'otros' end)

答案 1 :(得分:0)

<强>解决:

我采用了@Gordon Linoff概念并将其与this混合 @Gordon Linoff解决方案的问题在于订单中添加了行号。

SELECT @rn := @rn + 1 AS rn, SUM(superficie) AS superficie, (CASE WHEN @rn <= 4 THEN name ELSE "Other" END) AS especie
FROM (
    SELECT name, SUM(superficie) AS superficie
    FROM ciclos
    JOIN cultivos ON id_cultivo = idcultivo
    JOIN tbl_especies ON id_especie = idespecie
    WHERE fecha_cierre IS NULL
    GROUP BY id_especie
    ORDER BY superficie DESC
) AS temp
CROSS JOIN (SELECT @rn := 0) AS const
GROUP BY (CASE WHEN @rn <= 4 THEN name ELSE "Other" END)
ORDER BY superficie DESC

希望这有助于某人。谢谢你的帮助。