要说明PostgreSQL更新连接语句吗?

时间:2019-06-16 00:42:16

标签: sql postgresql

我似乎找不到任何能清楚说明某些update-join语句在PostgreSQL中如何工作的文档。假设数据库中有三个表:professorsclassesclassrooms。在professors表中,属性之一是class_id,这是引用classes表的外键。在classes表中,有一个classroom_id,引用了classrooms表。这是我感兴趣的命令:

UPDATE classes c SET year = 2
FROM classes cl
JOIN professors on cl.class_id = professors.class_id
JOIN classrooms on cl.classroom_id = classrooms.classroom_id
WHERE cl.class_id = c.class_id

这似乎为X = inner join(inner join(classes, professors), classrooms)中包含的每个类计算year = 2并更新X。它是否正确?此外,我不了解WHERE子句是如何做到这一点的。为什么这样做有效,为什么我不必使用IN关键字来完成此任务?

我希望对UPDATE... FROM... JOIN... WHERE语句在PostgreSQL中的作用进行简单而系统的解释。非常感谢!

2 个答案:

答案 0 :(得分:1)

我不确定这个解释是否真的是系统的,但是可以理解。

当您更新类时,它已经知道您要处理的表。实际上,我一般不会在FROM之后再引用该表,但是我确信在某些情况下,执行联接比使用WHERE更可取。

您的示例中的WHERE子句仅确保类表的两个实例都在处理相同的行。否则我想这将是一个外部联接。

在您的示例中,其他JOINS似乎没有意义。通常,当您想限制某些教授的更新时,例如WHERE Professors.professor ='Einstein'。

最后,正如我所提到的,我通常不第二次使用更新的表,而是使用。

UPDATE classes c SET year = 2
 FROM professors, classrooms 
 WHERE on c.class_id = professors.class_id
    AND c.classroom_id = classrooms.classroom_id

对我来说很好用,但是在某些情况下,其他语法更可取,特别是如果您需要左连接或类似的方法。

答案 1 :(得分:1)

我没有得到您的数据模型,因为似乎一位教授可以教授多门课程。

也就是说,您的查询是

UPDATE classes c
    SET year = 2
FROM classes c2 JOIN
     professors p
     ON c2.class_id = p.class_id JOIN
     classrooms cr
     ON c2.classroom_id = cr.classroom_id
WHERE c2.class_id = c.class_id;

正如您所期望的,FROM子句正在执行JOIN。您可以使用SELECT检查结果:

SELECT *
FROM . . . <the FROM clause here>

还发生了什么?好吧,UPDATE告诉Postgres更新表classes。忽略classes子句中的FROM(这是一个不同的引用)的事实。

它如何知道要更新哪些记录?好吧,WHERE子句说要更新与FROM匹配的行。在这种情况下,JOIN个正在执行过滤。

您还可以使用INEXISTS来表达这种逻辑:

UPDATE classes c
    SET year = 2
WHERE EXISTS (SELECT 1 FROM professors p WHERE c.class_id = p.class_id) AND
      EXISTS (SELECT 1 FROM classrooms cr WHERE c.classroom_id = cr.classroom_id);

我个人认为此版本的意图更加明确。