mesqueeb mesqueeb - 6 months ago 9
SQL Question

GROUP CONCAT concats too much duplicate values when LEFT JOINing two different tables

I have a query that fetches posts where I LEFT JOIN two tables:

Categories and tags: LEFT JOIN to the linking table → INNER JOIN to the category and tag names table.

LEFT JOIN wp_term_relationships AS term_link ON wpp.ID = term_link.object_id
INNER JOIN wp_terms AS terms ON term_link.term_taxonomy_id = terms.term_id


Extra post details as post meta:

LEFT JOIN wp_postmeta AS postmeta ON wpp.ID = postmeta.post_id


Now. I want to show all categories in a list with commas, with the MySQL GROUP_CONCAT:

GROUP_CONCAT(terms.name SEPARATOR ', ') AS allcatname


However, the problem is, because of my 2nd LEFT JOIN to wp_postmeta, somehow all the categories get copied for each wp_postmeta record to be found. So my 'allcatname' looks like this:


drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drinks, drink


So that happened...
The reason I want to keep GROUP_CONCAT is because I need it for filtering through "HAVING". So I'm looking for a way to show only one category per category record that's linked to each post: Let the group concat show. E.g. "drinks, soda, cola" if it has those three categories.

Here is the full Query:

SELECT
SQL_CALC_FOUND_ROWS
wpp.ID, wpp.post_title, wpp.post_author,
wpp.post_status,
GROUP_CONCAT(terms.name SEPARATOR ', ') AS allcatname
FROM wp_posts AS wpp

LEFT JOIN wp_term_relationships AS term_link ON wpp.ID = term_link.object_id
INNER JOIN wp_terms AS terms ON term_link.term_taxonomy_id = terms.term_id
LEFT JOIN wp_postmeta AS postmeta ON wpp.ID = postmeta.post_id

WHERE wpp.post_type = 'post'
AND wpp.post_warning <> 'no_image'
AND wpp.post_status <> 'trash'
AND wpp.post_status <> 'auto-draft'
AND (post_title LIKE '%$search_string%' OR postmeta.meta_value LIKE '%$search_string%')
GROUP BY wpp.ID
ORDER BY post_date DESC
LIMIT 20

Answer

Use:

GROUP_CONCAT(DISTINCT terms.name SEPARATOR ', ') AS allcatname

Instead of:

GROUP_CONCAT(terms.name SEPARATOR ', ') AS allcatname