Let's say I have this table:
item_id tag_id ------- ------ 1 1 1 2 2 2 2 3
As you can imagine, this is a table in which I have links to some elements and tags that belong to them. An item can have more than one tag, and one tag can be selected for more than one item.
Let's say I also have a special tag team (f.ex. tag_id = 50, 73, and 119) and a βitemsβ table with an identifier (specified by item_id ).
Is there an efficient query that gives me:
- number of items with these tags
- the elements themselves?
What i tried
SELECT COUNT(*) FROM ( SELECT COUNT(*) AS c FROM items_tags it JOIN items i ON i.id = it.item_id WHERE (tag_id=7 OR tag_id=95 OR tag_id=150) AND `status`='active' GROUP BY item_id ) t1 WHERE c=3 <
I can have both results, but with a very (apparently) inefficient query. After the exam with EXPLAIN, I would like to get rid of the βrangeβ given by the ORs.
Clarification of my problem: The problem is that I was given a very poorly written PHP framework that is repeated more than 900 times using various tag identifiers. Let's say you have one or more fixed identifiers (selected tags) and iterates over all 900+ tags to find the number of occurrences of elements that have common PLUS tags, iteration (this is a function to refine the search, showing only those elements which have all the tags plus one).
This code works as follows: I select one or more tags and their identifier is included in the query string. Say I selected tags 54 and 77. The code should find each element ID for elements that have BOTH tags 54 and 77, and list them one by one: we get a list of "elements with selected tags."
Then it offers a choice to refine the search, and here the odd part goes: the PHP code loop processes ALL 900+ tags, and for each iteration it takes a tag and counts how many elements ALL have 54, 77 tags and one for iteration. If count> 0, it displays the tag name with the account number, filtering out each tag whose elements do not have a link to the selected tags.
It would be nice to achieve the same result in a less intense way.