GROUP_CONCAT с несколькими объединениями - что мне не хватает? - PullRequest
1 голос
/ 08 октября 2019

Я понимаю, что это довольно распространенная проблема, поэтому я потратил много времени на изучение различных ответов, но ни один из них не помог решить мою проблему.

У меня есть система запросов на работу в PHP / MySQLи у меня проблемы с GROUP_CONCAT.

Вот моя схема:

job
job_id
job_title

worker
worker_id
worker_name

workermap
workermap_id
job_id
worker_id

Таблица, содержащая задания, работникстол для возможных рабочих и один для отображения рабочих на рабочие места. Задание может иметь одного или нескольких работников, работник может иметь одно или несколько заданий.

Когда задание регистрируется, оно создает запись в задание , но ничего в workermap пока кто-то специально не назначит работника. Это означает, что когда я запрашиваю задания, я делаю это с левым соединением, так как в workermap нет записей для каждого задания:

SELECT 
job.job_id,
job.job_title,
workermap.worker_id,
worker.worker_name

FROM job

LEFT JOIN workermap
ON job.job_id = workermap.job_id

LEFT JOIN worker
ON workermap.worker_id = worker.worker_id

Проблема в том, что это возвращает несколько строк, если естьНесколько рабочих назначены на работу:

+--------+-----------------------------+-------------+
| job_id | job_title                   | worker_name |
+--------+-----------------------------+-------------+
|    1   | New homepage                | Alan        |
|    1   | New homepage                | John        |
|    2   | Redesign footer             | John        |
|    2   | Redesign footer             | Sarah       |
|    3   | Update contact page content | NULL        |
+--------+-----------------------------+-------------+

То, что я хочу, это:

+--------+-----------------------------+-------------+
| job_id | job_title                   | worker_name |
+--------+-----------------------------+-------------+
|    1   | New homepage                | Alan, John  |
|    2   | Redesign footer             | John, Sarah |
|    3   | Update contact page content | NULL        |
+--------+-----------------------------+-------------+

Я понимаю, что мне нужно использовать CONCAT для объединения имен рабочих, но если я это сделаюэто:

SELECT 
job.job_id,
job.job_title,
GROUP_CONCAT(worker.worker_name)

FROM job

LEFT JOIN workermap
ON job.job_id = workermap.job_id

LEFT JOIN worker
ON workermap.worker_id = worker.worker_id

Затем я получаю только одну строку со всеми объединенными работниками:

+--------+--------------+----------------------+
| job_id | job_title    | worker_name          |
+--------+--------------+----------------------+
|    1   | New homepage | Alan,John,John,Sarah |
+--------+--------------+----------------------+

Я пробовал следующее:

SELECT 
job.job_id,
job.job_title,
workermap.worker_id,
workermap.worker_list

FROM job

LEFT JOIN 
    (
        SELECT workermap.worker_id, GROUP_CONCAT(worker_name) AS worker_list
        FROM workermap
        INNER JOIN worker
        ON workermap.worker_id = worker.worker_id
    )
AS workermap
SELECT 
job.job_id,
job.job_title,
(SELECT GROUP_CONCAT(worker.worker_name) 
FROM worker
WHERE worker.worker_id = workermap.worker_id)
AS combinedworkers

FROM job

LEFT JOIN workermap
ON job.job_id = workermap.job_id
SELECT 
job.job_id,
job.job_title,
workermap.worker_id,
worker.worker_list

FROM job

LEFT JOIN workermap
ON job.job_id = workermap.job_id

LEFT JOIN 
    (
        SELECT worker_id, GROUP_CONCAT(worker_name) AS worker_list
        FROM worker
        GROUP BY worker_id
    )
AS worker
ON workermap.worker_id = worker.worker_id

Ничто из этого не приблизило меня. Я уверен, что это относительно просто, но я не могу решить это. Спасибо!

1 Ответ

1 голос
/ 08 октября 2019

Это менее сложно, чем вы думаете. Вы можете просто использовать агрегирование на (job_id, job_title) и GROUP_CONCAT():

SELECT 
    j.job_id,
    j.job_title,
    GROUP_CONCAT(w.worker_name ORDER BY w.worker_name) worker_names
FROM job j
LEFT JOIN workermap wm ON job.job_id = wm.job_id
LEFT JOIN worker w ON wm.worker_id = w.worker_id
GROUP BY
    j.job_id,
    j.job_title
...