I have three tables:
events:
id | name
-------------------
1 | Test
2 | Another test
persons:
type | type_id | name | user_id
------------------------------------------------
event_organizer | 318 | NULL | 22
event_owner | 318 | Rob | NULL
event_owner | 318 | NULL | 6
user:
id | forname | surname
--------------------------
6 | Peter | Watson
7 | Chris | Brown
22 | Charlie | Teck
(Of course, the tables are much bigger than that, I just copied the relevant parts.)
This query:
SELECT event.*,
IF(persons.type='event_organizer', CONCAT_WS(', ', GROUP_CONCAT(forname, ' ', surname SEPARATOR ', '), GROUP_CONCAT(persons.name SEPARATOR ', ')), NULL) AS organizer_names,
IF(persons.type='event_owner', GROUP_CONCAT(forname, ' ', surname SEPARATOR ', '), NULL) AS owner_names
FROM event
LEFT JOIN persons ON persons.type_id = event.id AND (persons.type = 'event_owner' OR persons.type = 'event_organizer')
LEFT JOIN user ON user.id = persons.user_id
WHERE event.id=?
should output me all event data and the names of the owner and the organizer. The output I get is:
Array ( [id] => 318 [name] => Test [organizer_names] => Peter Watson, Rob, Charlie Teck [owner_names] => )
I don't get why owner_names is always empty. If I remove the organizer_names part:
SELECT event.*,
IF(persons.type='event_owner', GROUP_CONCAT(forname, ' ', surname SEPARATOR ', '), NULL) AS owner_names
FROM event
LEFT JOIN persons ON persons.type_id = event.id AND persons.type = 'event_owner'
LEFT JOIN user ON user.id = persons.user_id
WHERE event.id=?
Than I get the right owner (Rob and Peter Watson). I can also change it to:
SELECT event.*,
IF(persons.type='event_organizer', CONCAT_WS(', ', GROUP_CONCAT(forname, ' ', surname SEPARATOR ', '), GROUP_CONCAT(persons.name SEPARATOR ', ')), NULL) AS organizer_names,
IF(persons.type='event_owner', GROUP_CONCAT(forname, ' ', surname SEPARATOR ', '), NULL) AS owner_names
FROM event
LEFT JOIN persons ON persons.type_id = event.id AND persons.type = 'event_owner'
LEFT JOIN user ON user.id = persons.user_id
WHERE event.id=?
And this is working right too. So it seems that the second OR condition of the LEFT JOIN is destroying my owners :(
The reverse test (with same condition and without organizer_names):
SELECT event.*,
IF(persons.type='event_owner', GROUP_CONCAT(forname, ' ', surname SEPARATOR ', '), NULL) AS owner_names
FROM event
LEFT JOIN persons ON persons.type_id = event.id AND (persons.type = 'event_owner' OR persons.type = 'event_organizer')
LEFT JOIN user ON user.id = persons.user_id
WHERE event.id=?
brings also no owner_names output.
Where is my mistake?
GROUP BYclauses, and the random output it then produces. Best database ever <3 Read this article please, from beginning to end. Especially the part about 'non-deterministic nonsensical queries'.GROUP BYclause as required by aggegrate functions.