【问题标题】:Join three tables together to get one value将三个表连接在一起以获得一个值
【发布时间】:2019-09-22 18:13:35
【问题描述】:

我是 Postgresql 新手,我有三个表:

=# SELECT * FROM employee_names;
 employee_id | employee_name
-------------+---------------
           1 | Johannes
           2 | Günter
           3 | Elsabeth

=# SELECT * FROM projects;
 employee_id | last_project
-------------+--------------
           1 | 5
           2 | 15
           3 | 8

=# SELECT * FROM last_project_systems_used;
 employee_id | last_project | systems_used
-------------+--------------+--------------
           1 |            5 |           11
           1 |            5 |           18
           2 |           15 |            4
           3 |            8 |           10
           3 |            8 |            7
           3 |            8 |            2
  • employee_id in employee_names 是主键和序列号。
  • employee_name 是独一无二的。是的,我知道在典型的用例中,一个名字不应该被赋予独特的待遇,因为人们很容易拥有相同的名字,但在我的例子中它是独一无二的。
  • employee_id in projects 是主键。
  • last_project 不是空整数,数字可以在两个表中重复(他们工作的最后一个项目的项目号)
  • systems_used 是唯一的(他们处理的系统编号将始终是唯一值)

总结一下:

  • Johannes 的 employee_id 为 1,他的上一个项目是 #5,他在项目中同时使用了系统 11 和 18。
  • Günter 的 employee_id 为 2,他的上一个项目是 #15,他在项目中同时使用了系统 4。
  • Elsabeth 的 employee_id 为 3,她的上一个项目是 #8,她在项目中使用了系统 10、7 和 2。

我需要运行类似于以下内容的插入查询:

    INSERT INTO last_project_systems_used 
    VALUES ((SELECT employee_id FROM employee_names 
    WHERE employee_name = 'Günter'), 
    (SELECT last_project FROM projects 
    WHERE (SELECT employee_id FROM employee_name 
    WHERE employee_name = 'Günter')), 9);

这将检查 Günter (2) 的employee_id 是什么,找到他的最后一个项目编号是什么 (15) 并将系统编号 9 添加到表中。

该更新如下所示:

 employee_id | last_project | systems_used
-------------+--------------+--------------
           1 |            5 |           11
           1 |            5 |           18
           2 |           15 |            4
           3 |            8 |           10
           3 |            8 |            7
           3 |            8 |            2
           2 |           15 |            9

虽然我在从名为 Günter 的员工那里获得最后一个项目编号的部分遇到问题,因为项目表中只列出了他的 ID 而不是他的名字。

任何帮助将不胜感激。

【问题讨论】:

  • 您不应将last_project 存储在两个不同的表中。将其保存在projects 表中。如果您需要当前last_project_systems_used 格式的表格,请为该查询使用JOIN
  • 感谢@Bergi,这更优雅

标签: sql postgresql sql-update relationship sql-insert


【解决方案1】:

使用INSERT . . . SELECT:

INSERT INTO last_project_systems_used (employee_id, last_project, systems_used)
    SELECT en.employee_id, p.last_project, 9
    FROM projects p JOIN
         employee_names en
         ON p.employee_id = en.employee_id
    WHERE en.employee_name = 'Günter';

【讨论】:

  • 谢谢,但我得到了ERROR: column reference "employee_id" is ambiguous LINE 2: SELECT employee_id, last_project, 9 ,箭头指向employee_id。
  • 您可以使用USING 代替ON 作为连接条件,这会导致结果中只有一个employee_id 列。
  • @Bergi ERROR: syntax error at or near "p" LINE 5: USING p.employee_id = en.employee_id
  • @leetbacoon 有关正确语法,请参见 the docsFROM projects JON employee_names USING (employee_id)。或者,您可以在此处使用NATURAL JOIN
  • @leetbacoon 。 . .我本来应该限定所有列引用并修正答案。
【解决方案2】:

经过充分的反复试验,我发现这似乎可以解决问题,如果有更好的解决方案或者我的 SQL 听起来很糟糕,请告诉我。

INSERT INTO last_project_systems_used VALUES
((SELECT employee_id FROM employee_names
WHERE employee_name = 'Günter'),
(SELECT last_project FROM projects
WHERE employee_id = (SELECT employee_id FROM employee_names
WHERE employee_name = 'Günter')), 9);

【讨论】:

  • 是的,这听起来很糟糕,因为 SELECT employee_id FROM employee_names WHERE employee_name = 'Günter' 的重复。为避免在不使用 JOIN 的情况下出现这种情况,您可以使用嵌套查询:INSERT INTO last_project_systems_used SELECT (emloyee_id, (…), 9) FROM employee_names WHERE employee_name = 'Günter') 其中 部分是(SELECT last_project FROM projects WHERE projects.employee_id = employee_names.employee_id)
  • 感谢您的意见。如果 employee_name 被指定为 UNIQUE 会认为我的解决方案在功能上是合理的吗?
  • 功能上我猜是的,但代码重复仍然很糟糕。
  • 不要争论,但是重复代码怎么会不好呢?是不是比较慢?更容易出现错别字?一般是不好的做法?
  • 是的,它容易出错且不易维护。 en.wikipedia.org/wiki/Duplicate_code
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-20
  • 1970-01-01
  • 1970-01-01
  • 2018-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多