Zdá se, že se jedná o chybu v MySQL, o které jsem nahlásil . Zúžil jsem to na následující testovací případ, u kterého by se dalo očekávat, že vrátí jeden záznam (ale nevrací):
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
Podívejte se na to na sqlfiddle .
Ve vašem případě můžete udělat několik věcí, abyste to napravili:
-
Vyhněte se korelovanému poddotazu přepsáním jako spojení:
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
-
Pokud chcete zachovat korelovaný poddotaz (který může obecně poskytovat slabý výkon, ale je často snáze srozumitelný), použijte
WHERE
místoHAVING
: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
-
Pokud nemůžete změnit dotaz, měli byste zjistit, že vytvoření
people_stages.person_id
sloupec non-nullable problém vyřeší:ALTER TABLE people_stages MODIFY person_id BIGINT UNSIGNED NOT NULL
Zdá se, že mít index v tomto sloupci (který by byl vyžadován k provedení omezení cizího klíče) může také pomoci:
ALTER TABLE people_stages ADD FOREIGN KEY (person_id) REFERENCES people (id)
-
Alternativně lze odstranit
people_stages.person_id
z výběrového seznamu nebo upravte datový model/indexování/strategii dotazování, abyste se vyhnuli řazení souborů (v tomto případě nemusí být praktické, ale pro úplnost je zde uvádím).