-1

我有 3 张桌子:

  1. 具有以下字段的工人:worker_id、姓名、姓氏、
  2. 具有以下字段的任务:task_id、tasks_name、
  3. 表实现,包含worker_id和task_id

我必须选择worker_idnamesurnametask_name。问题是我不知道如何在选择数据时不复制worker_id(我必须显示worker的所有任务)。

我想出了一个查询,但正如我之前提到的,它对我不起作用(它重复了工人的 id)

SELECT workers.worker_id, workers.name, workers.surname, tasks.tasks_name 
FROM workers, tasks, implementing 
WHERE workers.worker_id=implementing.worker_id AND tasks.task_id=implementing.task_id
4

2 回答 2

0

你会得到类似的东西

+-----------+------+---------+------------+
| worker_id | 姓名 | 姓氏 | 任务名称 |
+-----------+------+---------+------------+
| 1 | 约翰 | 史密斯 | 任务 A |
| 1 | 约翰 | 史密斯 | 任务 B |
| 2 | 简 | 米勒 | 任务 C |
+-----------+------+---------+------------+

这正是它应该的样子。SQL 查询返回包含列和行的表。如果没有工人信息,一行的数据将是不完整的。CASE您可以使用表达式和分析函数(自 MySQL 8 起可用)来抑制这一点LAG,但您应该在显示数据的应用程序或网站中执行此操作。(这也是您决定是否为小数点分隔符显示逗号或点的地方。) SQL 是数据提供者,您的应用程序关心表示。

无论如何,这是在 MySQL 8 中执行此操作的查询:

select 
  case when w.worker_id = lag(w.worker_id) over (order by w.worker_id, t.task_id) then null else w.worker_id end as worker_id,
  case when w.worker_id = lag(w.worker_id) over (order by w.worker_id, t.task_id) then null else w.name end as name,
  case when w.worker_id = lag(w.worker_id) over (order by w.worker_id, t.task_id) then null else w.surname end as surname,
  t.tasks_name
from workers w
join implementing i on i.worker_id = w.worker_id
join tasks t on t.task_id = i.task_id
order by w.worker_id, t.task_id;
+-----------+------+---------+------------+
| worker_id | 姓名 | 姓氏 | 任务名称 |
+-----------+------+---------+------------+
| 1 | 约翰 | 史密斯 | 任务 A |
| | | | 任务 B |
| 2 | 简 | 米勒 | 任务 C |
+-----------+------+---------+------------+
于 2020-06-11T21:00:41.027 回答
0

问题是我不知道如何在选择数据时不复制worker_id(我必须显示worker的所有任务)。

看起来你想要字符串聚合。您可以将每个工作人员的所有任务作为逗号分隔的列表放在单个列中,并使用group_concat().

您可以使用连接或相关子查询来执行此操作,如下所示:

select
    w.worker_id,
    w.name,
    w.surname,
    (
        select group_concat(t.task_name)
        from implementing i
        inner join tasks t on t.task_id = i.task_id
        where i.worker_id = w.worker_id
    ) task_names
from worker w

请注意,这使用标准的显式连接(使用on关键字)而不是老式的隐式连接(在from子句中使用逗号):几十年前的这种语法使查询更难遵循和维护,不应该在新代码中使用.

于 2020-06-11T20:55:00.410 回答