2015-10-07 62 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 

這些都應該是相當於有了一個聚合,你可以,如果所有所需的性能匹配現有的財產很容易分辨。