简体   繁体   中英

Many To Many join with additional where

I think I have a somewhat trivial question but I can't figure out how this works. I have the following Companies and Products tables with a simple Many-To-Many relationship.

How would I have to extend this query, so that the results just contains let's say all companies which have products with id 1 AND 2?

I tried adding wheres and havings wherever I could imagine but all i could get was all companies which have products with id x (without the additional and)

Companies Table

id | name
-----------------
1  | Company 1
2  | Company 2
3  | Company 3

Companies_Products Table

id | product_id | company_id
----------------------------
1  | 1          | 1
2  | 2          | 1
3  | 3          | 1
4  | 1          | 2
5  | 1          | 3
6  | 2          | 3

Products Table

id | name
-----------------
1  | Product A
2  | Product B
3  | Product C

Statement

SELECT companies.name, 
       companies.id AS company_id, 
       products.id  AS product_id
FROM   companies 
       LEFT JOIN company_products 
              ON companies.id = company_products.company_id 
       INNER JOIN products 
               ON company_products.product_id = products.id 

If you want ALL companies with associated products 1 and 2, you can write this query:

SELECT c.name, 
   c.id AS company_id
FROM   companies c
WHERE (SELECT COUNT(*)
    FROM company_products cp
   WHERE cp.company_id = c.id
   AND cp.product_id in ('1', '2')
) = 2

Go to Sql Fiddle

If you want to know informations about associated product in the main query so you must use a join in addition of existing query.

Maybe you could using the following subquery in your query:

SELECT company_id, count(*) as no_companies
FROM Companies_Products
WHERE product_id IN (1, 2)
HAVING count(*) = 2

(In this case company an product must be coupled only once.) It returns all the company_ids with product 1 and 2.

There always some discussion about subquery's and performance, but I don't think you will notice.

You could make this function flexible by using a array.

pseudo code:
$parameter = array(1, 2);
...
WHERE  product_id IN $parameter
HAVING count(*) = count($parameter)

Please say so if you need more help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM