Reputation: 147
I can get nearly what I require, from a sql query but not quite and I would appreciate some help.
I have the following three tables:
people
+----+-------------------------+
| id | email |
+----+-------------------------+
| 1 | [email protected] |
| 2 | [email protected] |
| 3 | [email protected] |
+----+-------------------------+
jobs
+----+-------------+
| id | description |
+----+-------------+
| 1 | Plumber |
| 2 | Plasterer |
| 3 | Carpenter |
| 4 | Builder |
+----+-------------+
people_jobs
+-----------+--------+
| person_id | job_id |
+-----------+--------+
| 1 | 1 |
| 1 | 3 |
| 2 | 3 |
| 3 | 3 |
| 3 | 1 |
| 3 | 4 |
+-----------+--------+
Using this query I can output all the data in the format that I require:
SELECT people.id, people.email,
GROUP_CONCAT(DISTINCT jobs.description
ORDER By jobs.description DESC SEPARATOR ', ')
FROM jobs
INNER JOIN people_jobs On people_jobs.job_id = jobs.id
INNER JOIN people On people.id = people_jobs.person_id
GROUP BY people.id
As follows:
+----+-------------------------+----------------------------+
| id | email | GROUP_CONCAT |
+----+-------------------------+----------------------------+
| 1 | [email protected] | Plumber, Carpenter |
| 2 | [email protected] | Carpenter |
| 3 | [email protected] | Plumber, Carpenter,Builder |
+----+-------------------------+----------------------------+
By adding a WHERE clause I can optput all the people that can do a specific job:
SELECT people.id, people.email,
GROUP_CONCAT(DISTINCT jobs.description
ORDER By jobs.description DESC SEPARATOR ', ')
FROM jobs
INNER JOIN people_jobs On people_jobs.job_id = jobs.id
INNER JOIN people On people.id = people_jobs.person_id
WHERE jobs.description = 'Plumber'
GROUP BY people.id
+----+-------------------------+--------------+
| id | email | GROUP_CONCAT |
+----+-------------------------+--------------+
| 1 | [email protected] | Plumber |
| 3 | [email protected] | Plumber |
+----+-------------------------+--------------+
What I want to achieve is the above output plus the other jobs that the people can do as follows:
+----+-------------------------+----------------------------+
| id | email | GROUP_CONCAT |
+----+-------------------------+----------------------------+
| 1 | [email protected] | Plumber, Carpenter |
| 3 | [email protected] | Plumber, Carpenter,Builder |
+----+-------------------------+----------------------------+
Can anyone help please?
Upvotes: 3
Views: 38
Reputation: 72185
Use HAVING
clause instead:
SELECT people.id, people.email,
GROUP_CONCAT(DISTINCT jobs.description
ORDER By jobs.description DESC SEPARATOR ', ')
FROM jobs
INNER JOIN people_jobs On people_jobs.job_id = jobs.id
INNER JOIN people On people.id = people_jobs.person_id
GROUP BY people.id
HAVING COUNT(CASE WHEN jobs.description = 'Plumber' THEN 1 END) >= 1
HAVING
filters out people groups not having at least one job description equal to 'Plumber'
, whereas WHERE
operates per row, excluding all rows not having a job description equal to 'Plumber'
.
Upvotes: 2
Reputation: 1270401
In MySQL, you can add a simple having
clause, similar to the where
clause:
SELECT p.id, p.email,
GROUP_CONCAT(DISTINCT j.description ORDER By j.description DESC SEPARATOR ', ')
FROM jobs j INNER JOIN
people_jobs pj
On pj.job_id = j.id INNER JOIN
people p
On p.id = pj.person_id
GROUP BY p.id
HAVING SUM(j.description = 'Plumber') > 0;
Also, you probably do not need the DISTINCT
in the GROUP_CONCAT()
, unless your tables have duplicates.
Upvotes: 1
Reputation: 175934
You can wrap your first query with subquery and use FIND_IN_SET
:
SELECT *
FROM (
SELECT people.id, people.email,
GROUP_CONCAT(DISTINCT jobs.description
ORDER By jobs.description DESC SEPARATOR ', ') AS jobs
FROM jobs
JOIN people_jobs On people_jobs.job_id = jobs.id
JOIN people On people.id = people_jobs.person_id
GROUP BY people.id) AS sub
WHERE FIND_IN_SET('Plumber', sub.jobs) > 0;
But it will be slower than HAVING
approach in Giorgos Betsos answer.
Upvotes: 1