【问题标题】:SQL how to join these tablesSQL如何连接这些表
【发布时间】:2013-06-09 21:14:05
【问题描述】:

场景:

我有一个网站,可以让用户在他们最喜欢的汽车之间进行投票。汽车保存在cars 表中,投票保存在votes 中,cars 表中的 country_id 列引用countries(汽车品牌来自哪里)。

我想向用户显示哪个国家的投票最多。表格的简单版本:

汽车

id
name
country_id

国家

id
name

投票

id
user_id
car_id

理想情况下,我想向用户展示前 x 个国家/地区。以及他们都有多少票。

奖励:是否可以将此查询用于某个用户?因此,他们会看到他们投票选择的国家/地区的前 x。

您建议使用哪些索引?投票表可以增长到超过 1000 万票,汽车表也可以快速增长。

【问题讨论】:

  • 听起来 LEFT JOIN , GROUP BY , COUNT(*) 可以实现你的目标,不是吗?
  • 如果在可预见的未来投票数将增长到数千万行,您必须汇总投票并将它们保存在某个地方。
  • @mzedeler 你的意思是我应该把投票的 country_id 保存在投票表中吗?
  • 不 - 我会计算每个国家的选票并将它们保存在国家表中,并将每辆车的选票保存在汽车表中。请注意,这是多余的,但如果您有数百万行,那么您很可能会遇到性能问题而没有这样的事情。
  • @mzedeler 非常感谢,我明白你的意思。所以它可以做一个选择总和(投票)......加入国家?

标签: mysql sql database


【解决方案1】:

我认为您可以使用 LEFT JOIN 查询和 GROUP BY 聚合函数来实现此目的

SELECT COUNT(a.id) as total_votes, c.name as country_name
FROM Votes a
LEFT JOIN CARS b
ON a.car_id = b.id
LEFT JOIN Countries c
ON b.country_id = c.id
GROUP BY b.name, c.name
ORDER BY total_votes DESC

【讨论】:

  • group by 可以由 c.name、b.name 组成,因为一个国家可以有很多汽车投票
  • @fabio,我不明白查询的最后一部分:/ ON user_id = c.id,这不会检查 user_id 是否与国家 ID 相同吗?
  • @Kevin 对不起,我修好了
  • 我认为 c.id = b.country_id 在 fabio 的查询中
  • 也添加到这个查询可以是一个 WHERE 子句,它解决了这个问题的 BONUS 部分,即 WHERE a.user_id = x ,其中 x 是用户 id
【解决方案2】:

Cars.CountryID、Votes.UserID 和 Votes.CarID 上的索引似乎是合理的。正如 mzedler 建议的那样,当您达到数千万时,聚合可能不是一个好主意。

有多种方法可以解决这个问题,触发器、缓存或将投票日期添加到投票中,因此您可以一次性分解必须计算的记录数量。例如,每天缓存投票,然后只查询自午夜以来所做的投票,然后将它们相加。

【讨论】:

    猜你喜欢
    • 2014-01-02
    • 2022-11-15
    • 1970-01-01
    • 1970-01-01
    • 2021-02-04
    • 2020-12-02
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多