2011-01-11 94 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;