2015-10-13 62 views
0

案例: 我想已经COMPANY_ID 8和13,但所有的公司,只有当他们都product_ids(1,2,4,8)。选择行,其中枢轴具有所有的ID

问题: company_id 13没有product_id 4和8,但仍显示在查询结果中,如下所示。似乎cp.product_id IN(1,2,4,8)返回公司,如果它有这些值之一,但我需要他们在透视表company_products中具有所有这些值。

SELECT 
    c.id as company_id, 
    cp.product_id 
FROM 
    `companies` as c 
    LEFT JOIN `company_products` cp ON cp.company_id = c.id 
WHERE 
    c.id IN (8, 13) 
    AND cp.product_id IN (1,2,4,8) 
GROUP BY 
    c.id 

我的猜测是我应该使用IN以外的东西,但是我的研究并没有让我找到正确的解决方案。感谢您的帮助。

+0

当您说“_all所有拥有company_id 8和13_的公司”时,假设您确实是指“_company_id 8 OR 13_”是否正确?布尔值和/或在这里是重要的,'IN()'用作'OR'。我明白你的问题的部分内容,但其他WHERE条件需要澄清。如果您将输入行样本与该输入样本中的输出行一起提供,那么这将有所帮助,因此我们无需进行任何推理。 –

+0

在我的代码中,我已经确定我想company_id 8和13.我想过滤这两家公司的条件是具有所有给定的product_id –

回答

2

你可以一个having条款添加到您的查询,以确保每一个组c.id有四个cp.product_id:

SELECT 
    c.id as company_id 
FROM 
    `companies` as c 
    LEFT JOIN `company_products` cp ON cp.company_id = c.id 
WHERE 
    c.id IN (8, 13) 
    AND cp.product_id IN (1,2,4,8) 
GROUP BY 
    c.id 
HAVING COUNT(DISTINCT cp.product_id) = 4;  

Sample SQL Fiddle

如果您所需要的产品细节,你也可以将上述查询用作派生表并将其与产品表结合使用。

+0

该解决方案的工作原理虽然看起来在此解决方案中,但我将使用额外子句,而不是我应该(或可能)使用与IN不同的运算符。感谢您的解决方案。 –

+0

这是该问题的常见解决方案,因为您需要一个组来确定是否所有人都存在,并且在组后面应用“HAVING”。没有办法直接在'WHERE'中应用它,因为它仍在按行运行。 –

+0

@ChrisHessler据我所知,没有任何运算符会做你想做的事情,因为where子句在一行上操作,但你想要一次评估多行(你必须使用group by/having)。另一种方法是对company_product表使用多个连接,但效率不高。使用'intersect'的其他数据库应该是另一个(sub par)选项。 – jpw