【问题标题】:Multiple join with filtering带过滤的多重连接
【发布时间】:2019-07-26 01:11:18
【问题描述】:

我有 3 张桌子

idG


学生

idS 
idG


评分

idR
idS
date

关系是 1(Group)-∞(Student),1(Student)-∞(Rating)
我需要选择 idG 为 1 的所有组(例如)JOIN Student with LEFT JOIN Rating,其中日期介于两者之间。 我试图使用这样的查询

SELECT *
FROM `group` AS g
     JOIN student
        ON g.idG = 1
    LEFT JOIN rating
        ON rating.idR = student.idS
WHERE rating.`date` between '2019-02-01' and '2019-02-28';

此查询的结果集是在日期之间有评分的组的学生,但据我所知,左连接必须为在日期之间没有评分的学生获取 NULL 评分。我期待这个结果

idG | idS | idR  | date|
1   | 1   | NULL | NULL|
1   | 2   | 1    | 2019-02-08|
1   | 3   | 3    | 2019-02-10|
1   | 4   | NULL | NULL|

【问题讨论】:

  • date条件移动到最后一个ON子句中。
  • 将 WHERE 更改为 AND

标签: mysql sql join left-join


【解决方案1】:

您可以将左连接表的条件放在 JOIN 中。

SELECT grp.idG, stu.idS, rat.idR, rat.`date`
FROM student stu
JOIN `group` AS grp
  ON grp.idG = stu.idG
LEFT JOIN rating rat
  ON rat.idS = stu.idS 
 AND rat.`date` BETWEEN '2019-02-01' AND '2019-02-28'
WHERE stu.idG = 1;

LEFT JOIN 的问题是,当您还想要那些不匹配的内容时,连接表的 WHERE 子句中的条件将丢弃所有不匹配的内容。
因为它会丢弃连接右侧的 NULL。

【讨论】:

  • 太棒了,在 MySQL 中完美运行。一个问题,为什么不能加入学生组并加入评分?
  • 您也可以将 idG 的标准放入 JOIN 中。 F.e. ... AS grp ON grp.idG = stu.idG AND grp.idG = 1 ...。我只是把它放在 WHERE 子句中,因为它对我来说更像是一个搜索条件而不是链接条件。并且创建 JOIN 语法的目的是分离“搜索”和“链接”标准(与过时的逗号语法相比)。但这没有实际的“规则”。通常这是一种选择(除非查询优化器为一个选择生成一个缓慢的计划,而不是另一个)
  • 至于为什么加入rat.idS = stu.idS ,那是因为比较苹果和苹果而不是菠萝是有意义的。
  • 有道理,它仍然只是将其全部翻译成 HQL,因为由于某种原因我有重复的评级 =(
  • 好吧,我不知道您的数据或您实际尝试使用它实现的目标。但也许您可以在查询中添加 GROUP BY?并在适当的地方使用 COUNT / MAX / MIN / SUM / ...?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-26
  • 1970-01-01
  • 2020-10-17
  • 1970-01-01
  • 2014-06-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多