Sql 多个左连接之间的矛盾

Sql 多个左连接之间的矛盾,sql,left-join,Sql,Left Join,我试图理解以下由某个软件库自动生成的查询: SELECT DISTINCT `t`.* FROM `teacher` AS `t` LEFT JOIN `rel` AS `rel_profile` ON `rel_profile`.`field_id` = 2319 AND `rel_profile`.`item_id` = `t`.`id` LEFT JOIN `teacher_info` AS `profile` ON `profile`.`id` = `rel_pr

我试图理解以下由某个软件库自动生成的查询:

SELECT DISTINCT `t`.* FROM `teacher` AS `t` 
LEFT JOIN `rel` AS `rel_profile` 
    ON `rel_profile`.`field_id` = 2319 AND `rel_profile`.`item_id` = `t`.`id` 
LEFT JOIN `teacher_info` AS `profile` 
    ON `profile`.`id` = `rel_profile`.`related_item_id` 
LEFT JOIN `rel` AS `rel_profile_city` 
    ON `rel_profile_city`.`field_id` = 2320 AND `rel_profile_city`.`item_id` = `profile`.`id` WHERE `rel_profile_city`.`item_id` = 1
有三个左连接。我理解第一个和第二个。我不明白的是第三个左连接:

LEFT JOIN `rel` AS `rel_profile_city` 
    ON `rel_profile_city`.`field_id` = 2320 AND `rel_profile_city`.`item_id` = `profile`.`id` WHERE `rel_profile_city`.`item_id` = 1
rel
已在第一个左联接中使用:

LEFT JOIN `rel` AS `rel_profile` 
    ON `rel_profile`.`field_id` = 2319 
现在,同一个表再次左键联接,但这次联接字段的值不同:

LEFT JOIN `rel` AS `rel_profile_city` 
    ON `rel_profile_city`.`field_id` = 2320 

这两个连接为什么不矛盾?

此查询将显示
教师
rel
中与
字段id=2319
字段id=2320
关联的行。此查询将显示
教师
rel
中与
关联的行
字段id=2319
字段id=2320

彼此并不“矛盾”。假设您有一个用户表,其中包含用户的人口统计和个人数据。和另一个用户之间具有“关系”的表。因此,在这个“关系”表中,有列
UserId1
UserId2
。如果希望查询返回这两个用户的数据,则需要对表
users
进行两次
联接,每个
User
列一次。这并不意味着他们互相矛盾

两者之间没有“矛盾”。假设您有一个用户表,其中包含用户的人口统计和个人数据。和另一个用户之间具有“关系”的表。因此,在这个“关系”表中,有列
UserId1
UserId2
。如果希望查询返回这两个用户的数据,则需要对表
users
进行两次
联接,每个
User
列一次。这并不意味着他们互相矛盾

查询正在使用别名:

`rel` AS `rel_profile`
假设表
rel
实际上是一个名为
rel\u profile
的表。然后在查询的其余部分使用该别名。我不确定MySQL,但在其他一些数据库系统上,从那时起将表称为
rel
(*)是一个错误(除非有另一个连接重新引入表并且不提供别名)

并且允许多次加入同一个表-只要名称(或别名)是唯一的。当您试图构造依赖于同一表中多行内容的结果时,这非常有用,其中结果应占用一行



(*)“Then forwards”是按照处理条款的顺序,而不是文本顺序。例如,您应该在
SELECT
子句中使用别名,因为即使它在文本上出现较早,它(概念上)也是在
FROM
子句之后处理的。

查询使用别名:

`rel` AS `rel_profile`
假设表
rel
实际上是一个名为
rel\u profile
的表。然后在查询的其余部分使用该别名。我不确定MySQL,但在其他一些数据库系统上,从那时起将表称为
rel
(*)是一个错误(除非有另一个连接重新引入表并且不提供别名)

并且允许多次加入同一个表-只要名称(或别名)是唯一的。当您试图构造依赖于同一表中多行内容的结果时,这非常有用,其中结果应占用一行



(*)“Then forwards”是按照处理条款的顺序,而不是文本顺序。例如,您应该在
SELECT
子句中使用别名,因为即使它在文本上出现较早,它(在概念上)也是在
FROM
子句之后处理。

您以不同的别名联接了同一个表的两个不同副本-如果这是您所要求的,它不会尝试以两种不同的方式联接表的一个副本。第三个左联接实际上由于“where”而变成硬联接条件,因为它将结果集限制为此表的“item_id”为“1”的记录。无论如何,它正在为与顶级教师记录关联的“related_item_id”引入属性信息,因此“t”(teacher)包含基本结果集,“rel_profile”(rel)包含配置文件属性信息,“profile”(teacher_info)如果“rel_profile”列中存在“rel_item_id”值,并且“rel_profile_city”是相关信息(如果存在)的属性信息,则扩展属性信息。您已以不同别名连接了同一表的两个不同副本-如果需要,它不会尝试以两种不同的方式连接表的一个副本根据“where”标准,第三个左连接实际上变成了硬连接,因为它将结果集限制为该表的“item_id”为“1”的记录。无论如何,它正在为与顶级教师记录关联的“related_item_id”引入属性信息,因此“t”(teacher)包含基本结果集,“rel_profile”(rel)包含配置文件属性信息,“profile”(teacher_info)如果“rel_profile”列中存在“rel_item_id”值,并且“rel_profile_city”是相关信息的属性信息(如果存在),则扩展属性信息。