Search code examples
mysqlsqljoin

How can I select records that match multiple values in a linking table using a MySQL join statement?


I'm trying to fix a query used for product filtering that works fine for a single category, but is very wrong when multiple categories are selected. The query is currently selecting all products whose id's match one cat_id OR another, which is a start, but I can't figure out how to only get the products whose id's match BOTH chosen cat_id's in categories_linked.

Here's an example of the query that is currently running when two filters are selected:

SELECT A.* FROM products A LEFT JOIN categories_linked B ON A.id = B.prod_id WHERE (B.cat_id = 1 || B.cat_id = 2) GROUP BY A.id;

For example, if I filtered by cat_id 1 and 2, I would want the product with id 1 returned, but currently it returns products with id's 1, 2 and 3. The WHERE clause is generated dynamically, so if it can be maintained, even better.

categories_linked

cat_id|prod_id|
------+-------+
     1|      1|
     1|      2|
     2|      1|
     2|      3|

products

id |title |
---+------+
  1| item1|   
  2| item2|  
  3| item3|    

Solution

  • Thanks to /u/r3pr0b8 on Reddit for the help.

    SELECT products.* 
      FROM ( SELECT prod_id
              FROM categories_linked  
              WHERE cat_id IN ( 1 , 2 )
             GROUP
                 BY prod_id
             HAVING COUNT(DISTINCT cat_id) = 2
           ) AS these       
    INNER
      JOIN products
        ON products.id = these.prod_id