【问题标题】:How to SUM values of a column and then order by another column using SQL?如何对列的值求和,然后使用 SQL 按另一列排序?
【发布时间】: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_votes31,20stateAR。这是什么逻辑
  • 您的第一个查询无效。如果您没有收到语法错误,则表明您没有SET sql_mode = 'ONLY_FULL_GROUP_BY';,因此正在使用 MySQL 不幸提供的臭名昭著的作弊模式。是的,状态和数字在结果中是完全任意的; MySQL 从候选的任何行中挑选它们。 (它在幕后默默地将ANY_VALUE 应用到这些列上。)namecandidate 的错字还是这又是一个列?
  • 好的,那么您有一个违反数据库规范化的表。你最好有一个单独的表格,每个候选人持有该数字一行。然后就可以使用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


【解决方案1】:
SELECT state, ANY_VALUE(number), candidate, SUM(votes) AS tt_votes   
FROM table   
GROUP BY state, candidate     
ORDER BY state, candidate;

【讨论】:

  • 此查询仍然无效 - 您要选择哪个号码?在ORDER BY 中包含选票也没有任何意义,因为结果中每个州和候选人只有一个结果行。而且您已经从 OP 的查询中复制了选择列表,其中“name”可能是“candidate”的拼写错误。
  • 很好 @ThorstenKettner,我确实更改了 OP 的查询,现在将对其进行编辑
  • @ThorstenKettner 是的,你是对的。这是另一个错字。
  • 我已编辑查询并将ANY_VALUE 应用于“数字”,以使其成为有效查询而不会出现语法错误。顺便说一句,答案会更好,您是否解释了查询的作用以及它如何解决任务。不要发布仅代码的答案。
猜你喜欢
  • 2014-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-14
  • 2011-01-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多