2011-01-11 4 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

Какие РСУБДы? SQL-Server, Oracle, MySQL, ... –

+0

Я не совсем уверен, что вы хотите - можете ли вы опубликовать, как должен выглядеть вывод для этого примера? – Martin

+0

@Peter Database - SQLite – evilone

ответ

1

Плохая новость заключается в том, что вы не можете сделать это в SQLite, по крайней мере, с этой структурой данных, так как SQLite не поддерживает рекурсивные функции SQL или окна.

Если выбрать производительность важна, вы можете попытаться организовать данные, как это: http://articles.sitepoint.com/article/hierarchical-data-database/2

Другой вариант заключается в добавлении корневой идентификатор для каждой строки во время ввода.

В принципе, в какой-то момент вам придется использовать несколько выборок и определить идентификатор корня на уровне приложения.

Обновление: Хорошо, это очень псевдокод, но он должен доставить вас туда.

Вам нужен язык, который имеет какой-то тип хэш-карты или имени массива.

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; 
+0

Но как я могу это сделать, с несколькими запросами, если структура таблиц остается прежней? – evilone

+0

Я добавил код, надеюсь, это поможет. – Martin

+0

Язык - Delphi – evilone

Смежные вопросы