mysql选择数据,不重复id

m0rkklqb  于 2021-07-29  发布在  Java
关注(0)|答案(2)|浏览(342)

我有三张table:
带字段的工人:工人id、姓名、姓氏,
包含以下字段的任务:任务id、任务名称,
表,其中包含worker\u id和task\u id
我必须选择 worker_id , name , surname ,和 task_name . 问题是我不知道如何在选择数据时不复制worker\u 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
vaj7vani

vaj7vani1#

你会得到

+-----------+------+---------+-----------+
| worker_id | name | surname | task_name |
+-----------+------+---------+-----------+
|         1 | John | Smith   | TASK A    |
|         1 | John | Smith   | TASK B    |
|         2 | Jane | Miller  | TASK C    |
+-----------+------+---------+-----------+

而这正是它应该的样子。sql查询返回列和行的表。如果没有工作者信息,行的数据将是不完整的。你可以用 CASE 表达式和解析表达式 LAG 功能(MySQL8提供),但您更应该在显示数据的应用程序或网站中执行此操作(这也是您决定是否显示逗号或小数点分隔符的地方。例如,作为数据供应商,您的应用程序关心显示。
总之,在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 | name | surname | task_name |
+-----------+------+---------+-----------+
|         1 | John | Smith   | TASK A    |
|           |      |         | TASK B    |
|         2 | Jane | Miller  | TASK C    |
+-----------+------+---------+-----------+
mw3dktmi

mw3dktmi2#

问题是我不知道如何在选择数据时不复制worker\u 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 子句):几十年前的这种语法使查询更难遵循和维护,不应该在新代码中使用。

相关问题