first question from me and it’s a bit of a complex one, so do guide me through any etiquette you’re all used to! Right, bit of a complex one here so I shall describe what I want first before going into code.
MySQL database, I have a table of organisations, a table of services, and a table that cross-references organisations with services. I’m building a search function that will retrieve the organisations that match ANY selected services, but will sort them based on how many services they match AND list what those services are.
OK, the pertinent bits of code n whatnot:
Organisations table (organisations):
id: INT, AI
name: VARCHAR(150)
Services table (services):
id: INT, AI
name: VARCHAR(150)
Cross-reference table (xref_org_services):
org_id: INT
service_id: INT
I can get a list of organisations that match any of the services I search for:
SELECT DISTINCT organisations.name AS org
FROM organisations
JOIN xref_org_services ON organisations.id=xref_org_services.org_id
WHERE xref_org_services.services_id IN (x, y, z)
ORDER BY org ASC
where x, y, z would be the ID of the services I’ve selected. Done, not a problem.
Now I want to return how many services each of the organisations match, and what they are. I’ve had a try with
SELECT organisations.name AS org, COUNT(xref_org_services.services_id) AS matched
but that’s giving me the number of rows matched total which isn’t what I want. Am I looking at a nested SELECT somewhere to do the count?
Ultimately, my output needs to go something like this:
Org_1 matched 4 services
- Serv_1
- Serv_3
- Serv_4
Org_2 matched 3 services
- Serv_1
- Serv_2
- Serv_4
Org_3 matched 1 service
- Serv_2
Am I making any sense at all? Let me throw some “data” into this then to see if I can clarify things a bit.
organisations:
id | name
-------------------------
1 | A1 Train
2 | Faux LLC
3 | Shakey Practice
services:
id | name
-------------------------
1 | PTS
2 | Track safety
3 | Assessors
4 | Structural
5 | Signalling
xref_org_services:
org_id | services_id
-------------------------
1 | 1
1 | 2
1 | 4
2 | 1
2 | 4
3 | 5
So, this means:
- A1 Train offers PTS, Track Safety and Structural
- Faux LLC offers PTS and Structural
- Shakey Practice offers Signalling
If I want to retrieve all organisations that offer PTS, Track Safety and Structural I want the output to say something along the lines of:
A1 Train matched
- PTS
- Track Safety
- Structural
Faux LLC matched
- PTS
- Structural
I hope this makes sense. Pointers, hints, full answers all welcome. Let me know if you need clarifications or further information.
Thanks
You want to use
GROUP BY: