我正在尝试理解以下由某些软件库自动生成的查询:
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
为什么这两个连接不矛盾?
答案 0 :(得分:2)
查询使用别名:
`rel` AS `rel_profile`
假设表rel
实际上是一个名为rel_profile
的表。然后在整个查询的其余部分使用该别名。我不确定MySQL,但在其他一些数据库系统上,从那时开始将表引用为rel
是错误的(*)(除非有另一个重新引入表的连接而不是提供别名)。
允许多次加入同一个表 - 只要名称(或别名)是唯一的。当您尝试构建依赖于同一表中多个行的内容的结果时,这非常有用,其中结果应占据一行。
(*)“然后继续”按照处理子句的顺序,而不是文本顺序。例如。你应该使用SELECT
子句中的别名,因为即使它在文本上更早出现,它也会(在概念上)在FROM
子句之后处理。
答案 1 :(得分:1)
此查询将显示teacher
中rel
与field_id = 2319
或 field_id = 2320
答案 2 :(得分:1)
彼此并不“矛盾”。想象一下,您有一个用户表,其中包含用户的人口统计和个人数据。另一个表与用户之间的“关系”。因此,在此“关系”表格中,您有列UserId1
和UserId2
。如果您想要一个返回这两个用户数据的查询,则需要对表JOINS
执行两次Users
,每个User
列一次。这并不意味着它们相互矛盾。