DISTINCT działa na wszystkich kolumnach w SELECT, więc jeśli wybierasz wszystko, zwróci każdy odrębny wiersz, a nie tylko odrębne posty. Aby obejść ten problem, możesz po prostu WYBRAĆ dane z tabeli postów, a następnie ODRÓŻNIĆ je, tj.
SELECT DISTINCT posts.*
Ale powiedziałeś też, że chciałbyś, jeśli to możliwe, postów i informacji o kotach. Jednym ze sposobów, aby to zrobić i zachować jeden wiersz na post, jest użycie GROUP_CONCAT więc Twoje zapytanie może skończyć się mniej więcej tak.
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
Wprowadziłem kilka innych zmian w pierwotnym zapytaniu, takich jak zmiana pierwszego sprzężenia na INNER JOIN i dodanie filtrów cats/tags do warunków JOIN dla odpowiednich tabel.
ps, gdy mówisz, że masz oddzielne tabele dla kotów i tagów, aby przyspieszyć generowanie list, może się okazać, że jedna poprawnie zaindeksowana tabela byłaby równie szybka, a także uprościłaby Twój kod.