【问题标题】:SQL SUM top 5 values then JOIN resultsSQL SUM 前 5 个值,然后 JOIN 结果
【发布时间】:2013-05-12 22:01:59
【问题描述】:

我想返回投票最多的前 5 个项目,按投票数排序。 我想最好的方法是将每一行的votes_upvotes_down 相加,然后取其中的前 5 个并将其与另一个表连接。

这是我现有的表,Items.ID 映射到 Votes.item_ID:

Items
+----+--------+---------+
| ID |  name  | site_ID |
+----+--------+---------+
| 10 | box    |     111 |
| 11 | hammer |     222 |
| 12 | drill  |     333 |
| 13 | nail   |     444 |
+----+--------+---------+

Votes
+----+---------+----------+------------+
| ID | item_ID | votes_up | votes_down |
+----+---------+----------+------------+
|  1 |      10 |       25 |         20 |
|  2 |      11 |      200 |        100 |
|  3 |      12 |      100 |         50 |
|  4 |      13 |       50 |         20 |
+----+---------+----------+------------+

这些是我想要返回的结果:

+--------+-------+
|  name  | votes |
+--------+-------+
| hammer |   100 |
| drill  |    50 |
| nail   |    30 |
| box    |     5 |
+--------+-------+

【问题讨论】:

标签: mysql sql join sum


【解决方案1】:
SELECT   Items.name, votes_up-votes_down AS votes_num
FROM     Items, Votes
WHERE    Items.id = Votes.item_id
ORDER BY votes_num DESC
LIMIT    5;

数据库先做JOIN再做LIMIT,否则很可能会丢失元组。如果您使用的是 MySQL 或 PostgreSQL,您可以使用 EXPLAIN SELECT ... 语句验证这一点。如果你想先做top 5,你必须手动做:

SELECT I.name, V.votes_num AS votes_num
FROM   Items I, 
  (SELECT item_ID, votes_up-votes_down AS votes_num
   FROM   Votes ORDER BY votes_num DESC LIMIT 5) V
WHERE  I.ID = V.item_ID
ORDER BY votes_num DESC;

查看此demo;它会返回你想要的结果。

NAME    VOTES_NUM
hammer  100
drill   50
nail    30
box     5

【讨论】:

  • 谢谢,限制5部分怎么样?
  • @RyanKoehler 如果您使用的是 MySql 或 postgresql,则可以使用 LIMIT 5。请参阅我更新的帖子。
  • 这种方式是先加入所有行再限制,还是先找到前5行再加入?
  • @RyanKoehler SQL 默认情况下不会首先进行限制,因为它可能会丢失元组。您可以使用EXPLAIN SELECT ... 查看系统生成的查询计划(如果您使用的是 MySQL 或 PostgreSQL)。
  • 谢谢,我需要在第二个示例的最后一行添加另一个 ORDER BY votes_num DESC
【解决方案2】:
SELECT i.name AS name, v.votes_up-v.votes_down AS votes
FROM items AS i
JOIN votes AS v ON v.item_id=i.id
ORDER BY votes DESC
LIMIT 5 ;

我认为SELECT TOP 5 是 MS SQL 语法。

【讨论】:

  • 可以在order by子句中使用别名,例如ORDER BY votes DESC
  • 我没有意识到你可以做到这一点。这将使 ad hoc 查询更容易。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-07
  • 2022-01-15
  • 1970-01-01
相关资源
最近更新 更多