DISTINCT fungerar på alla kolumner i SELECT, så har du valt allt kommer det att returnera varje distinkt rad och inte bara de distinkta inläggen. För att komma runt detta kan du bara VÄLJA data från inläggstabellen och sedan DISTINERA den, dvs.
SELECT DISTINCT posts.*
Men du har också sagt att du skulle vilja ha inlägg och kattinformation också om det är möjligt. Ett sätt att göra detta och behålla en rad per inlägg är att använda GROUP_CONCAT så din fråga kan sluta ungefär så här.
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
Jag har gjort ett par andra ändringar i din ursprungliga fråga, som att ändra den första anslutningen till en INNER JOIN och lägga till filtren för katter/taggar i JOIN-villkoren för de relevanta tabellerna.
ps när du säger att du har separata tabeller för katter och taggar för att påskynda genereringen av listor, kanske du upptäcker att en tabell som är korrekt indexerad skulle vara lika snabb och skulle också förenkla din kod.