SQL和外键的逻辑问题

时间:2015-04-05 14:16:51

标签: mysql sql foreign-keys constraints

EDITED * 1

我是一名软件开发人员,因此我对MySQL-Database没有多少经验。

我想为任务写一张票,它包含工人的详细信息以及需要哪个工人。

我在数据库中有一个表,其中包含forname,surname和worker的部门。

表格worker如下所示:

+---------+---------+----------+------------+
| id (PK) | surname | forename | department |
+---------+---------+----------+------------+
| 1       | bar     | foo      | shop       |
+---------+---------+----------+------------+
| 2       | baz     | foo      | production |
...

tasks看起来像这样:

+---------+------------+----------+-------------+----------------+-------------------+----
| id (PK) | task       | shop_req | shop_worker | production_req | production_worker | ...
+---------+------------+----------+-------------+----------------+-------------------+----
| 1       | do sth.    | yes      | 1           | yes            | 2                 | ...
+---------+------------+----------+-------------+----------------+-------------------+----
| 2       | do sth.    | no       | (NULL)      | yes            | 2                 | ...
...

我该如何将它们连接在一起?

我试过这个SQL代码: * 1

ALTER TABLE tasks

ADD CONSTRAINTS FK_tasks_shop
FOREIGN KEY (shop_worker) 
REFERENCES worker(id) 
ON UPDATE RESTRICT
ON DELETE RESTRICT,

ADD CONSTRAINTS FK_tasks_production
FOREIGN KEY (production_worker) 
REFERENCES worker(id) 
ON UPDATE RESTRICT
ON DELETE RESTRICT

当我使用以下SQL代码调用表tasks时:

SELECT a.id, a.task, a.shop_req, CONCAT(b.surname, ', ', b.forename) AS shop_worker,
a.production_req, CONCAT(c.surname, ', ', c.forename) AS production_worker
FROM tasks AS a
JOIN worker AS b ON a.shop_worker = b.id
JOIN worker AS c ON a.production_worker = c.id

结果是:

+----+------+----------+-------------+----------------+-------------------+----
| id | task | shop_req | shop_worker | production_req | production_worker | ...
+----+------+----------+-------------+----------------+-------------------+----

这意味着结果只是没有行的列的名称 我希望得到以下结果:

+----+------------+----------+-------------+----------------+-------------------+----
| id | task       | shop_req | shop_worker | production_req | production_worker | ...
+----+------------+----------+-------------+----------------+-------------------+----
| 1  | do sth.    | yes      | bar, foo    | yes            | baz, foo          | ...
+----+------------+----------+-------------+----------------+-------------------+----
| 2  | do sth.    | no       | (NULL)      | yes            | baz, foo          | ...
...

这里有什么问题?我无法找到错误 是否有一种有效的方法来调用SQL代码?

非常感谢您的回答!

2 个答案:

答案 0 :(得分:0)

首先,您的查询缺少AS a的{​​{1}}别名,这会使查询失败。添加之后,您应该返回一行,但是......

由于您希望包含tasks表中的所有行,即使tasksshop_worker没有匹配的行,您也要使用production_worker代替像这样:

left join

Sample SQL Fiddle

有关各种联接的详细介绍,请参阅:A Visual Explanation of SQL Joins

答案 1 :(得分:0)

您需要left join而不是inner join

SELECT 
a.id, 
a.task,
a.shop_req, 
CONCAT(b.surname, ', ', b.forename) AS shop_worker,
a.production_req, 
CONCAT(c.surname, ', ', c.forename) AS production_worker
FROM tasks a
left join worker b ON a.shop_worker = b.id
left join worker c ON a.production_worker = c.id