Đây dường như là một lỗi trong MySQL, về lỗi mà tôi đã gửi báo cáo . Tôi đã thu hẹp nó thành trường hợp thử nghiệm sau, trường hợp này sẽ trả về một bản ghi duy nhất (nhưng không):
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
Xem nó trên sqlfiddle .
Trong trường hợp của bạn, bạn có thể thực hiện một số cách để khắc phục điều này:
-
Tránh truy vấn con tương quan bằng cách viết lại dưới dạng một phép nối:
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
-
Nếu bạn muốn giữ lại truy vấn con tương quan (thường có thể mang lại hiệu suất kém nhưng thường dễ hiểu hơn), hãy sử dụng
WHERE
thay vìHAVING
: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
-
Nếu bạn không thể thay đổi truy vấn, bạn nên thấy rằng tạo
people_stages.person_id
cột non-nullable sẽ giải quyết được vấn đề:ALTER TABLE people_stages MODIFY person_id BIGINT UNSIGNED NOT NULL
Có vẻ như việc có một chỉ mục trên cột đó (sẽ được yêu cầu để thực hiện một ràng buộc khóa ngoại) cũng có thể giúp ích:
ALTER TABLE people_stages ADD FOREIGN KEY (person_id) REFERENCES people (id)
-
Ngoài ra, người ta có thể xóa
people_stages.person_id
từ danh sách được chọn hoặc điều chỉnh mô hình dữ liệu / chiến lược lập chỉ mục / truy vấn để tránh sắp xếp tệp (có thể không thực tế trong trường hợp này, nhưng tôi đề cập đến chúng ở đây để hoàn thiện).