2015-10-07 38 views
1

我有一个问题,使复杂的查询更容易,而无需使用PHP构建查询。MySQL的几个内部连接和子查询

我的问题:

产品可以有几个特性如。颜色,大小和状态。 要得到它具有所有3个属性我可以一个产品:

products p 

INNER JOIN product_propeties p1 on p.pid = p1.pid AND p1.property = 1 (color) 

INNER JOIN product_propeties p2 on p.pid = p2.pid AND p2.property = 2 (size) 

INNER JOIN product_propeties p3 on p.pid = p3.pid AND p3.property = 3 (state) 

这工作得很好。我会得到所有这3个属性的所有产品。

我的问题是现在我不想用PHP生成p1,p2,p3。这些属性列在“property_groups”表中。在这个表中,我可以将属性分组。

proberty|title|group_name 

1|color|winterspecial 

2|size|winterspecial 

3|state|winterspecial 

我想加入“property_groups”表“winterspecial”,并从上面我不知道我有多么的例子。问题是每个属性都需要存在。几个单一的连接完成这项工作。但是如何在单个MySQL查询中执行此操作。

使用PHP我选“winterspecial”然后我建立与P1,P2查询...

必须有一个更好的办法。注意这些属性必须是AND连接。 OR很容易,这将是一个简单的子选择。

INNER JOIN product_propeties p1 on p.pid = p1.pid AND product_propeties IN (
    SELECT * FROM property_groups WHERE "winterspecial" 
) 
+0

我不明白。你想显示一个产品的所有属性?而不是'玩具','绿色','15'','破碎',你想选择'玩具','颜色=绿色','尺寸= 15'','状态=破碎'?还有什么?请显示所需的输出。 –

+0

请记住,子查询和联接是相同的东西,速度也不慢。 – Mjh

+0

@Mjh。 。 。它们在功能上等同,但不一定以相同的方式实施。 OP。 。 。请编辑问题并提供样本数据和期望的结果。一个完整的查询也可能表达你正在尝试做什么。 –

回答

0

这可能看起来有点笨拙,但我可以在瞬间想出的唯一的事情...

为了知道一个产品是否具有所有winterspecial特性,我们可以指望所有现有的冬季特性和产品的冬季特性,然后比较这两个数字。

然后我们可以在产品ID是在发现了一套从产品和product_properties选择:

select ... 
from products p 
join product_properties pp on pp.pid = p.pid and pp.property in 
    (select property from property_groups where group_name = 'winterspecial') 
where p.pid in 
(
    select pid 
    from product_properties 
    where property in 
    (select property from property_groups where group_name = 'winterspecial') 
    group by pid 
    having count(*) = 
    (select count(*) from property_groups where group_name = 'winterspecial') 
); 
0

唉唉,我想我现在明白了问题。对于给定的组,您似乎希望所有具有property_groups表中属性的产品。

这是一种方法。执行cross join以生成产品和属性列表。然后执行left join以匹配product_properties

select p.* 
from products p cross join 
    property_groups g left join 
    product_properties pp 
    on pp.pid = p.id and pp.property = g.property 
where g.group_name = 'winterspecial' 
group by p.id 
having count(distinct pp.property) = count(distinct g.property) 

实际上,你可以简单地having子句的其中之一:

having sum(pp.property is null) = 0   -- no null values 
having count(pp.property) = count(g.property) -- all match 

这些都应该是相当于有了一个聚合,你可以,如果所有所需的性能匹配现有的财产很容易分辨。