1

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

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 

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

4

3 回答 3

2

该查询使用别名:

`rel` AS `rel_profile`

说要假装桌子rel实际上是一张叫做 的桌子rel_profile。然后在整个查询中使用该别名。我不确定 MySQL,但在其他一些数据库系统上,rel从那时起 (*) 引用表是错误的(除非有另一个连接重新引入表并且不提供别名)。

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


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

于 2013-01-28T15:16:06.453 回答
1

彼此并不“矛盾”。想象一下,您有一张用户表,其中包含用户的人口统计和个人数据。另一个表是用户之间的“关系”。所以,在这个“关系”表中,你有列UserId1UserId2. 如果您想要一个返回这两个用户数据的查询,您需要对JOINStable执行两次Users,每User列一次。这并不意味着它们相互矛盾。

于 2013-01-28T15:05:18.903 回答
1

此查询将显示与ORteacher关联的行relfield_id = 2319 field_id = 2320

于 2013-01-28T15:01:45.337 回答