Reputation: 516
I have a query, generated by DataMapper (an ORM for CodeIgniter) that is returning results on one server, but not on another.
Both databases are exactly the same. The query works on servers with MYSQL versions 5.1.41, 5.1.63 and 5.5.20, and fails on 5.1.52.
The query is:
SELECT DISTINCT `clients`.`id`
FROM (`clients`)
LEFT OUTER JOIN `clients_locations`
clients_locations ON `clients`.`id` = `clients_locations`.`client_id`
LEFT OUTER JOIN `locations`
locations ON `locations`.`id` = `clients_locations`.`location_id`
LEFT OUTER JOIN `reports`
location_reports ON `locations`.`id` = `location_reports`.`location_id`
WHERE
`location_reports`.`id` = 1
AND
`clients`.`id` = 2
I've done some testing, and I've found the following things out:
If you just have 1 WHERE clause, it returns results.
If you change any of the operators to LIKE, != etc, it returns results
If you change the AND to an OR, it returns the results.
Similar queries are used throughout the site, so I don't know why it is this one that's failing. For instance:
SELECT DISTINCT `clients`.`id`
FROM (`clients`)
LEFT OUTER JOIN `clients_locations`
clients_locations ON `clients`.`id` = `clients_locations`.`client_id`
LEFT OUTER JOIN `locations`
locations ON `locations`.`id` = `clients_locations`.`location_id`
LEFT OUTER JOIN
`locations_questionnaires` location_locations_questionnaires
ON
`locations`.`id` = `location_locations_questionnaires`.`location_id`
WHERE
`location_locations_questionnaires`.`questionnaire_id` = 3
AND
`clients`.`id` = 2
returns the correct results on all the servers listed above.
Has anyone seen this before?
To clarify:
I can't edit the SQL, as it's produced by an ORM.
Both datasets are EXACTLY the same.
The issue is why the query doesn't return any results on one server, when it does on the other.
UPDATE: I've just upgraded the server to 5.1.61, and the query runs fine. So looks like it's a bug in 5.1.52.
Upvotes: 1
Views: 2445
Reputation: 77876
Try doing it like this:
SELECT DISTINCT `clients`.`id`
FROM (`clients`)
LEFT OUTER JOIN `clients_locations`
clients_locations ON `clients`.`id` = `clients_locations`.`client_id`
AND `clients`.`id` = 2
LEFT OUTER JOIN `locations`
locations ON `locations`.`id` = `clients_locations`.`location_id`
LEFT OUTER JOIN `reports`
location_reports ON `locations`.`id` = `location_reports`.`location_id`
AND `location_reports`.`id` = 1
Upvotes: 1
Reputation:
The WHERE condition on an outer joined table, e.g.
WHERE location_reports.id = 1
effectively turns the outer join into an inner join. If you move that condition into the JOIN condition, it works correctly (as you have already noticed).
The reason is that the WHERE condition is applied after the JOINs, as the outer joined rows do not have a value for location_reports.id
the condition is false for them and they are removed from the result.
Upvotes: 2