Wygląda na to, że jest to błąd w MySQL, o którym złożyłem raport . Zawęziłem to do następującego przypadku testowego, w którym można by oczekiwać zwrócenia pojedynczego rekordu (ale tak nie jest):
CREATE TABLE t (x INT NULL); -- table with nullable column
INSERT INTO t VALUES (0); -- but non null data
SELECT a.x -- select our nullable column
FROM t a, (SELECT NULL) b -- joining it with anything at all
WHERE EXISTS ( -- but filter on a subquery
SELECT *
FROM (SELECT NULL) c -- doesn't really matter what
HAVING a.x IS NOT NULL -- provided there is some correlated condition
-- on our nullable column in the HAVING clause
)
ORDER BY RAND() -- then perform a filesort on the outer query
Zobacz go na sqlfiddle .
W Twoim przypadku możesz zrobić kilka rzeczy, aby to naprawić:
-
Unikaj skorelowanego podzapytania, przepisując je jako sprzężenie:
SELECT * FROM people AS p LEFT JOIN (people_stages AS s NATURAL JOIN ( SELECT person_id, MAX(created) created FROM people_stages GROUP BY person_id ) t) ON s.person_id = p.id ORDER BY p.last_name
-
Jeśli chcesz zachować skorelowane podzapytanie (które generalnie może dawać słabą wydajność, ale często jest łatwiejsze do zrozumienia), użyj
WHERE
zamiastHAVING
:SELECT * FROM people AS p LEFT JOIN people_stages AS s ON s.person_id = p.id WHERE s.created = ( SELECT MAX(created) FROM people_stages WHERE person_id = s.person_id ) ORDER BY p.last_name
-
Jeśli nie możesz zmienić zapytania, powinieneś zauważyć, że
people_stages.person_id
kolumna non-nullable pozwoli obejść problem:ALTER TABLE people_stages MODIFY person_id BIGINT UNSIGNED NOT NULL
Wydaje się, że posiadanie indeksu w tej kolumnie (co byłoby wymagane do wprowadzenia ograniczenia klucza obcego) może również pomóc:
ALTER TABLE people_stages ADD FOREIGN KEY (person_id) REFERENCES people (id)
-
Alternatywnie można usunąć
people_stages.person_id
z listy wyboru lub dostosuj model danych/indeksowanie/strategię zapytań, aby uniknąć sortowania plików (w tym przypadku może to nie być praktyczne, ale wspominam o nich tutaj dla kompletności).