DISTINCT hoạt động trên tất cả các cột trong CHỌN, vì vậy nếu bạn đang CHỌN mọi thứ, nó sẽ trả về từng hàng riêng biệt chứ không chỉ các bài đăng riêng biệt. Để hoàn thành điều này, bạn chỉ có thể CHỌN dữ liệu từ bảng bài đăng và sau đó KHẮC PHỤC nó, tức là
SELECT DISTINCT posts.*
Nhưng bạn cũng đã nói rằng bạn cũng muốn các bài đăng và thông tin về mèo nếu có thể. Một cách để làm điều này và giữ một hàng cho mỗi bài đăng là sử dụng GROUP_CONCAT vì vậy truy vấn của bạn có thể kết thúc như thế này.
SELECT
posts.*,
GROUP_CONCAT(cats.id SEPARATOR ',') as catsList,
GROUP_CONCAT(tags.id SEPARATOR ',') as tagsList
FROM posts
INNER JOIN termRelations ON ( posts.id = termRelations.postId )
LEFT JOIN cats ON ( termRelations.termId = cats.id AND termRelations.termTypeId = 1 AND cats.id =5 )
LEFT JOIN tags ON ( termRelations.termId = tags.id AND termRelations.termTypeId = 0 AND
(tags.id =2
OR tags.id =1)
)
GROUP BY posts.id
LIMIT 0 , 30
Tôi đã thực hiện một số thay đổi khác đối với truy vấn ban đầu của bạn như thay đổi phép nối đầu tiên thành INNER JOIN và thêm bộ lọc mèo / thẻ vào điều kiện JOIN cho các bảng có liên quan.
ps khi bạn nói rằng bạn có các bảng riêng biệt cho mèo và thẻ để tăng tốc độ tạo danh sách, bạn có thể thấy rằng một bảng được lập chỉ mục chính xác sẽ nhanh không kém và cũng sẽ đơn giản hóa mã của bạn.