【问题标题】:SQL Join data from 3 tables来自 3 个表的 SQL 连接数据
【发布时间】:2017-08-02 21:29:11
【问题描述】:

我有 3 个表:
skill_categories(id, name) -- 类别列表
skills(id, skill_category_id, name) -- 每个技能类别的子类别
contributors(id, name, skill_id_1, skill_id_2, skill_id_3) -- 一个人最多可以拥有 3 个技能

我想查询贡献者中每个skill_id 字段的skill_category_id, skill_category_name, skill_id and skill_name

根据我的阅读,我认为可以使用 SQL JOIN 来实现这一点,并编写了这样的查询。

SELECT s.skill_category_id AS skill_category_id, 
       sc.name AS skill_category_name,
       s.id AS skill_id, 
       s.name AS name
FROM skills AS s
INNER JOIN skill_categories AS sc 
      ON s.skill_category_id = sc.id
INNER JOIN contributors AS c
      ON c.skill_id_1 = s.id
      OR c.skill_id_2 = s.id
      OR c.skill_id_3 = s.id
WHERE c.id = $id
ORDER BY s.name, sc.name ASC

这是执行此类查询的最佳方式吗?

【问题讨论】:

  • 使用内部选择会更快
  • 前面和后面的断言都是错误的。这似乎是有效的解决方案。定义最佳。
  • 执行 SQL 子查询 Turion。比 JOINS 上的 OR 更容易和更快
  • 可以简化为ON s.id IN (c.skill_id_1, c.skill_id_2, c.skill_id_3)
  • 最好的解决方案是规范您的设计。而不是多个skill_id_X 列,而是有一个将贡献者ID 与技能相关联的多对多表。那么你将不会有 3 个技能的任意限制。

标签: php mysql sql join


【解决方案1】:

不,这不是最好的方法——尤其是从性能的角度来看。 OR(或IN)是连接的性能杀手。

最好添加更多连接,每个技能类别一个。所以,这应该有更好的性能:

SELECT s.skill_category_id AS skill_category_id,  sc.name AS skill_category_name,
       s.id AS skill_id,  s.name AS name
FROM skills s INNER JOIN
     skill_categories sc 
     ON s.skill_category_id = sc.id LEFT JOIN
     contributors c1
     ON c.skill_id_1 = s.id LEFT JOIN
     contributors c2
     ON c1.skill_id_2 = s.id LEFT JOIN
     contributors c3
     ON c3.skill_id_3 = s.id
WHERE $id in (c1.id, c2.id, c3.id)
ORDER BY s.name, sc.name ASC

如果每个技能有单独的行而不是单独的列,查询会更简单。

【讨论】:

  • 你能解释一下为什么你使用 LEFT JOINs 作为 Skill_id 吗?
  • @turion 。 . .因为它们可能并不都存在。您不想过滤掉$id 匹配第一个技能但其他两个是NULL 的行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-15
  • 1970-01-01
  • 1970-01-01
  • 2014-11-16
  • 1970-01-01
相关资源
最近更新 更多