1

I am trying to display articles with tags. The query below works perfect.

This is my query:

SELECT
    item.item_id,
    item.item_title,
    item.item_createdate,
    GROUP_CONCAT(tag.tag_name) AS TagName
FROM
    item
LEFT JOIN `item-tag` ON `item-tag`.item_id = item.item_id
LEFT JOIN tag ON tag.tag_id = `item-tag`.tag_id
    /*WHERE item.item_type = 1*/
GROUP BY
    item.item_id
ORDER BY
    item_createdate
DESC

enter image description here enter image description here

The problem I am having starts when I filter the results. If I want to see the results for the "Tag 1" I add the where clause:

 WHERE tag.tag_name = 'Tag 1'

this removes the other tags from the GROUP_CONCAT and I get this result:

enter image description here

How can I get the tagged articles and also display the additional tags for that article?

5
  • Have you tried using WHERE tag.tag_name LIKE '%Tag 1%'? That way, it won't matter if there are multiple tag names as long as that one exists. Commented Nov 8, 2017 at 21:41
  • @Zeke i have already tried that. it didn`t work. Commented Nov 8, 2017 at 21:44
  • Sometimes it takes me a while to get LIKE to work as well, are you using prepared statements? Commented Nov 8, 2017 at 21:46
  • no, i am trying it on phpmyadmin. This works: WHERE tag.tag_name IN(SELECT tag_name FROM tag) but i might have too many tags. so it is not a good option Commented Nov 8, 2017 at 21:48
  • 1
    @Zeke This worked. I think the Select only returns the tag ids from the join instead of all. (SELECT tag_id FROM tag where tag.tag_id = item-tag.tag_id) Commented Nov 8, 2017 at 22:04

2 Answers 2

1

Try:

WHERE EXISTS 
    (SELECT tag_id FROM tag 
    JOIN `item-tag` tmp ON tag.tag_id = tmp.tag_id 
    WHERE tmp.item_id = item.item_id AND tag.tag_name = 'Tag 1')

Note that filters on the tag_name don't work, because GROUP_CONCAT and GROUP BY logically generate a larger table, then concatenate results from this. Filtering out too early removes entries from this larger table, so the tags can't appear in the concatenation.

The alternate approach is to use your existing query as a subquery, and surround it with

SELECT * FROM (...existing query...) as foo
WHERE TagName LIKE '%Tag 1%'
Sign up to request clarification or add additional context in comments.

5 Comments

it is still displaying the articles tagged with 'Tag 1'
this worked. WHERE tag.tag_id IN (SELECT tag_id FROM tag where tag.tag_id = item-tag.tag_id)
@emre This won't be specific to 'Tag 1' though, surely? I have edited the answer to add a join
yeah, it didn't work. I thought it did. Your one worked. will it be more efficient than WHERE tag.tag_name IN(SELECT tag_name FROM tag)
If there are many tags for one item, then it could be more efficient, because the EXISTS version can return true as soon as one is found, rather than generating the complete list. In practice, I don't think you are going to have many tags called 'Tag 1' corresponding to the same item_id, so it doesn't matter
1
SELECT
  item.item_id,
  item.item_title,
  item.item_createdate,
GROUP_CONCAT(tag.tag_name) AS TagName
FROM
  item
LEFT JOIN `item-tag` ON `item-tag`.item_id = item.item_id
LEFT JOIN tag ON tag.tag_id = `item-tag`.tag_id

--limit your existing query by only including item_ids with 'Tag 1'
WHERE item.item_id IN(
    SELECT `item-tag`.item_id
    FROM tag INNER JOIN `item-tag` ON tag.tag_id=`item-tag`.tag_id
    WHERE tag.tag_name=?
    )

GROUP BY
  item.item_id
ORDER BY
  item_createdate
DESC

Note that I used a placeholder which would be used in a prepared statement. For PHPMyAdmin, of course, just put the value in place of the ?

Personal preference-- I would name the table item_tag so that you don't have to use those pesky backslashes...

1 Comment

thanks Tim. I wanted to use IN clause but couldn't get it working. Your solution works perfect.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.