一次更新多行

时间:2020-11-03 00:31:21

标签: arrays postgresql sql-update where-clause

请考虑以下情况:

我有三个表:StudentStudentCourseCourse

Student包含有关学生的信息以及作为主键的唯一id(uuid)。

Course包含课程的唯一id(uuid)(主键)和课程的name(文本)。

StudentCourse通过将courseId(uuid)与studentId(uuid)相关联来跟踪学生学习的课程。 courseId是从id引用Course的FK,studentId是从id引用Student的FK。

假设我在Student中有以下一行:

id                name
--------------------------
student_id_john  John Doe

Course(3行):

id               name
---------------------------
biology_id       Biology
mathematics_id   Mathematics
physics_id       Physics

StudentCourse(1行):

studentId         courseId
----------------------------
student_id_john   physics_id

因此,当前John Doe上物理课。

我想更新StudentCourse表以反映新的变化:用“数学”课程代替“物理”课程,并为John Doe添加“生物学”课程。

假设我有以下数组(大小可能有所不同):

let course_arr = ["Mathematics", "Biology"]

我想通过以下方式更新StudentCourse表:

  1. 首先从id中选择适当的Course,其中name =“数学”,name =“生物学”
  2. 更新现有行(在courseId中设置mathematics_id = StudentCourse,其中studentId = student_id_john
  3. 插入新行:studentId = student_id_johncourseId = biology_id

是否可以在一个查询中完成所有这些操作?我只想访问我的数据库一次。我试图避免多次调用数据库。

我尝试了以下查询(将“物理”课程替换为“数学”课程),但是它不起作用:

update student_course 
set "courseId"  = subquery.id
from (select id from course where name = 'Mathematics') as subquery
where "studentId" = student_id_john

1 个答案:

答案 0 :(得分:0)

如果您真的坚持只用一个语句来做:

WITH new_courses AS (
   SELECT '["Mathematics", "Biology"]'::jsonb AS values
), remove AS (
   DELETE FROM student_course
   USING course, new_courses
   WHERE student_course."courseId" = course.id
     AND student_course."studentId" = student_id_john
     AND NOT (to_jsonb(course.name) <@ new_courses.values)
)
INSERT INTO student_course ("studentId", "courseId")
SELECT student_id_john, course.id
FROM course
WHERE to_jsonb(course.name) <@ new_courses.values;