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”是相关信息的属性信息(如果存在),则扩展属性信息。