【发布时间】:2022-01-25 15:19:00
【问题描述】:
当我SELECT * FROM table; 我有以下结果:
+-------+--------+-------------+-------+
| state | number | candidate | votes |
+-------+--------+-------------+-------+
| AR | 12 | CANDIDATE A | 9 |
| AR | 12 | CANDIDATE A | 23 |
| LA | 12 | CANDIDATE A | 19 |
| OK | 12 | CANDIDATE A | 2 |
| TX | 12 | CANDIDATE A | 7 |
| TX | 12 | CANDIDATE A | 7 |
| AR | 25 | CANDIDATE B | 2 |
| LA | 25 | CANDIDATE B | 5 |
| LA | 25 | CANDIDATE B | 1 |
| OK | 25 | CANDIDATE B | 17 |
| OK | 25 | CANDIDATE B | 21 |
| TX | 25 | CANDIDATE B | 7 |
| LA | 17 | CANDIDATE C | 14 |
| LA | 17 | CANDIDATE C | 42 |
| OK | 17 | CANDIDATE C | 13 |
| OK | 17 | CANDIDATE C | 5 |
| TX | 17 | CANDIDATE C | 1 |
| TX | 17 | CANDIDATE C | 4 |
+-------+--------+-------------+-------+
所以我尝试将总票数与SUM(votes) as tt_votes 相加,然后按候选人对结果进行分组以得到一个 desc 顺序。
SELECT state, number, name, SUM(votes) as tt_votes
FROM table
GROUP BY candidate
ORDER BY tt_votes DESC;
+-------+--------+-------------+----------+
| state | number | candidate | tt_votes |
+-------+--------+-------------+----------+
| LA | 17 | CANDIDATE C | 79 |
| AR | 12 | CANDIDATE A | 67 |
| TX | 25 | CANDIDATE B | 53 |
+-------+--------+-------------+----------+
state 列显示候选人的第一个(或最后一个?)记录,但我真正想要的不仅是按候选人分组,而且首先按州分组以获得这样的结果:
+-------+--------+-------------+----------+
| state | number | candidate | tt_votes |
+-------+--------+-------------+----------+
| AR | 12 | CANDIDATE A | 32 |
| AR | 25 | CANDIDATE B | 2 |
| AR | 17 | CANDIDATE C | 0 |
| LA | 17 | CANDIDATE C | 56 |
| LA | 12 | CANDIDATE A | 19 |
| LA | 25 | CANDIDATE B | 6 |
| OK | 25 | CANDIDATE B | 38 |
| OK | 17 | CANDIDATE C | 18 |
| OK | 12 | CANDIDATE A | 2 |
| TX | 12 | CANDIDATE A | 14 |
| TX | 25 | CANDIDATE B | 7 |
| TX | 17 | CANDIDATE C | 5 |
+-------+--------+-------------+----------+
它按字母顺序列出州,然后按 tt_votes 列出每个州顺序中每个候选人的 tt_votes。
例如尝试了 UNION 或插入 WHERE state = AR,但没有成功。
有什么想法可以做到吗?
编辑
如果我使用 (SELECT state, ANY_VALUE(number), Candidate, SUM(votes) as tt_votes WHERE state = 'AR' GROUP BY state, number, Candidate) UNION ((SELECT state, ANY_VALUE(number), Candidate, SUM(votes) as tt_votes WHERE state = 'LA' GROUP BY state, number, Candidate) UNION (SELECT state, ANY_VALUE(number), Candidate, SUM(votes) as tt_votes WHERE state = 'OK' GROUP BY state, number,候选人);等等。我有我们需要的东西。但是有没有更好的方法来做到这一点?
【问题讨论】:
-
如果我正确理解您的需求,请使用
GROUP state,number,candidate ORDER BY state, tt_votes DESC -
您是如何到达
tt_votes的31,2和0的state是AR。这是什么逻辑 -
您的第一个查询无效。如果您没有收到语法错误,则表明您没有
SET sql_mode = 'ONLY_FULL_GROUP_BY';,因此正在使用 MySQL 不幸提供的臭名昭著的作弊模式。是的,状态和数字在结果中是完全任意的; MySQL 从候选的任何行中挑选它们。 (它在幕后默默地将ANY_VALUE应用到这些列上。)name是candidate的错字还是这又是一个列? -
好的,那么您有一个违反数据库规范化的表。你最好有一个单独的表格,每个候选人持有该数字一行。然后就可以使用GSM的查询,把
SELECT state, number, name, SUM(votes) as tt_votes改成SELECT state, ANY_VALUE(number), candidate, SUM(votes) as tt_votes。 -
是的。
UNION在这里不合适,您需要UNION ALL,因为没有要删除的重复项。然后您可以从GROUP BY中删除“数字”,因为您在其上使用了聚合函数ANY_VALUE)。如果您想将其限制为 AR、LA 和 OK,那么只需使用WHERE state IN ('AR', 'LA', 'OK'),您就完成了。无需将多个查询的结果与UNION ALL粘合在一起。
标签: mysql sql sum mariadb sql-order-by