具有LIMIT的列的Mysql SUM

时间:2014-03-04 10:50:29

标签: mysql group-by sum limit

我的这张表直接来自Excel格式的Excel格式。 我订购了本年度,以及降序的飞行员积分, 然后是每个骑手的前六个结果的总和 (如果行小于或等于6,我只需要添加行) 然后从结果表中提取前三个最佳结果,以便建立排名。

提前致谢

INSERT INTO `migliorio` (`Anno`, `Pilota`, `km`, `punti`, `media`) 
VALUES (2013, 'Pilota 2', 6.33, 6.33, 21.86),
       (2013, 'Pilota 2', 4.75, 4.75, 15.15),
       (2013, 'Pilota 2', 4.07, 4.07, 11.84),
       (2013, 'Pilota 1', 9.73, 9.73, 19.61),
       (2013, 'Pilota 1', 6.97, 9.76, 9.56),
       (2013, 'Pilota 1', 7.59, 7.59, 26.27),
       (2013, 'Pilota 1', 8.18, 8.18, 24.56),
       (2013, 'Pilota 1', 7.24, 7.24, 12.27),
       (2013, 'Pilota 1', 11.77, 11.77, 17.20),
       (2013, 'Pilota 2', 5.98, 5.98, 18.68),
       (2013, 'Pilota 2', 6.09, 7.31, 15.60),
       (2013, 'Pilota 2', 10.99, 13.19, 13.20),
       (2013, 'Pilota 3', 20.29, 24.35, 18.72),
       (2013, 'Pilota 3', 29.30, 35.16, 18.39),
       (2013, 'Pilota 1', 10.34, 10.34, 13.88),
       (2013, 'Pilota 1', 7.65, 10.71, 14.55),
       (2013, 'Pilota 1', 8.21, 8.21, 27.53),
       (2013, 'Pilota 1', 13.57, 16.28, 11.94);

2 个答案:

答案 0 :(得分:0)

SELECT DISTINCT T0.Pilota,
(SELECT SUM(km) FROM migliorio WHERE Pilota = T0.Pilota LIMIT 6) As SUM_km,
(SELECT SUM(punti) FROM migliorio WHERE Pilota = T0.Pilota LIMIT 6) As SUM_punti,
(SELECT SUM(media) FROM migliorio WHERE Pilota = T0.Pilota LIMIT 6) As SUM_media
 FROM `migliorio` AS T0
ORDER BY (SELECT SUM(media) FROM migliorio WHERE Pilota = T0.Pilota) DESC
LIMIT 3

表格构造的提示。在此查询中,我链接名称字段(Pilota)。使用具有Pilot ID的int ID字段。这是因为:

  1. 查询更快
  2. 使用主键防止重复密钥
  3. 值中没有拼写错误(例如“Pilota 1”和“Pilota1”不相同)

答案 1 :(得分:0)

使用变量,如下所示: -

SELECT `Pilota`, SUM(`km`), SUM(`punti`), SUM(`media`)
FROM 
(
    SELECT `Anno`, `Pilota`, `km`, `punti`, `media`, @seq:=if(@prev_pilota = Pilota, @seq + 1, 1) AS aSeq, @prev_pilota := Pilota
    FROM migliorio
    CROSS JOIN (SELECT @seq := 0, @prev_pilota := '') Sub1
    ORDER BY `Anno`, `Pilota`, `km`, `punti`, `media`
) Sub0
WHERE aSeq <= 6
GROUP BY Pilota

SQL小提琴: -

http://www.sqlfiddle.com/#!2/7310f/4

但是不确定你想如何选择哪个km / punti / media是你想要的每个Pilota(或者你想要每个Pilota和Anno?)

编辑 - 修改为只为每个pilota / anni的前6个点总结: -

SELECT `Pilota`, Anno, SUM(`punti`)
FROM 
(
    SELECT `Anno`, `Pilota`, `km`, `punti`, `media`, @seq:=if(@prev_pilota = Pilota and @prev_anno = anno, @seq + 1, 1) AS aSeq, @prev_pilota := Pilota, @prev_anno := anno
    FROM migliorio
    CROSS JOIN (SELECT @seq := 0, @prev_pilota := '', @prev_anno :=0) Sub1
    ORDER BY `Anno`, `Pilota`, `punti` DESC
) Sub0
WHERE aSeq <= 6
GROUP BY Pilota, Anno

编辑 - 一个简短的解释

这使用子查询,设置几个SQL变量。这些初始化序列号(@seq),前一个pilota(@prev_pilota)和前一个anno(@prev_anno)。

主子查询然后从表migliorio获取所有记录,由anno,pilota和punti命令(降序为punti)。这样,一个pilota / anno的所有记录将在一起。如果pilota和anno与存储的pilota和anno(存储在@prev_pilota和@prev_anno中)相同,则将@seq加1,如果没有,则将@seq设置为1,并将该行的@seq保存到列名称ASEQ。这样,pilota / anno的每一行都有一个序列号。对于一个pilota / anno,序列号将是1,因为punti下降,所以序列号将会上升。

外部查询获取此子查询的结果,并总结一个pilota / anno的Punti值(由GROUP BY指定),但WHERE子句检查aSeq是&lt; = 6,所以任何除了序号在1到6之间的导航/ anno的行被忽略。

希望有所帮助