2011-01-11 95 views
0

我有兩個表:接收產品類別和產品與一個查詢

Product 
------------------------------------ 
id group_id name quick_select 
------------------------------------ 
1  1  product1  1 
2  3  product2  0 
3  5  product3  1 

Product_group 
----------------------- 
id name parent_id 
----------------------- 
1 group1  0 
2 group2  0 
3 group3  1 
4 group4  1 
5 group5  3 

我做快速選擇產品的導航系統。我向用戶和用戶顯示的類別可以通過點擊類別按鈕在其中導航,然後逐級下降到子類別,並下降到最終不能更深入的級別,然後顯示產品。首先,我會展示根類別,其中包含產品的根類別以及這些根類別的子類別,子類別等。

在我的查詢中,我希望選擇所有根目錄類別(其中parent_id = 0),如果其中包含產品及其子類別和子子目錄等等,其中產品表中的quick_select必須爲1。我不知道類別的深度 - 有多少層次。

一個查詢可能嗎?或者我需要做兩個查詢?

我做了,到目前爲止,該查詢:

SELECT pg.id, pg.name, pg.parent_id AS parent_id 
FROM product_group AS pg 
LEFT JOIN product AS p ON pg.id = p.group_id 
WHERE pg.parent_id = 0 AND p.id IS NOT NULL AND p.quick_select = 1 
GROUP BY pg.id 

但我沒有收到根類,其子類是空的,其子類是空的,這下多一個子類別的產品與quick_select = 1 。

對不起,我的英語不好。

我想收到的所有類別,其中產品quick_select = 1時,而不是產品

-- Category 
|  | 
| product 
| 
-- Category 
     | 
    Category 
     | 
    Category 
     | 
multiple products 
+0

哪個RDBMS? SQL服務器,甲骨文,MySQL,... – 2011-01-11 10:38:17

+0

我不太清楚你想要什麼 - 你可以發佈輸出應該看起來像這個例子? – Martin 2011-01-11 10:39:05

回答

1

壞消息是,你不能做到這一點SQLite中,至少有這種數據結構,因爲SQLite的不支持遞歸SQL或窗口函數。

如果選擇性能很重要,你可以嘗試舉辦這樣的數據: http://articles.sitepoint.com/article/hierarchical-data-database/2

另一種選擇是根ID在輸入時間添加到每一行。

基本上,在某些時候,您將不得不使用多個選擇並確定應用程序級別的根ID。

更新: 好吧,這是非常多的僞代碼,但它應該讓你在那裏。

您需要一種具有某種散列表或命名數組數據類型的語言。

hashmap results, parent, nodes, nodes_new; # variables 


foreach (res in sql_execute("SELECT id, parent_id FROM product_group;")) { 
    parent[res.id] = res.parent_id; 
} 

# get groups with products 
foreach (res in sql_execute("SELECT pg.id FROM product_group AS pg INNER JOIN 
     product AS p ON pg.id = p.group_id 
     WHERE p.quick_select = 1 GROUP BY pg.id ")) { 
    nodes[res.id] = res.id; 
} 

while (length(nodes) > 0) { 
    foreach (i in nodes) { 
     if (i = 0) { results[i] = i; } # if its a root node, add to results 
     else { nodes_new[parent[i]] = parent[i]; } # otherwise, add parent to the next round 
    } 
    nodes = nodes_new; # prepare for next round 
} 

print results;