есть талица с полями id, pid, name
я делаю так в двух запросах
$parent = mysql_query('SELECT id, pid, name FROM cat;'); // вывожу родителей
$row_parent = mysql_fetch_assoc($parent) // это я циклю while
$children = mysql_query('SELECT id, pid, name FROM cat WHERE pid = '.$row_parent['id']); // вывожу детей
$row_children = mysql_fetch_assoc($children) // это я циклю while
получается вывод
- Фрукты
- - Спелые
- - Яблоко
- - Груша
- - Лимон
- Хлеб
- - Чёрный
- - Белый
как нужно составить запрос чтобы выборка была категорий и под категорий одним запросом
Спустя 40 минут, 45 секунд (25.08.2010 - 00:38) Rivalryzerg написал(а):
Немного не хватает данных для вопроса: сколько уровней подкатегорий?
Если рассмотреть вариант для двух уровней:
Не вижу ничего страшного получать данные в двух запросах.
1) выбираем категории
В цикле получаем массив категорий, а так же формируем переменную $ids вида "1, 3, 6, 23, 56, .."
2) получаем подкатегории
Есть ли весомые причины городить один сложный запрос и его дополнительно обрабатывать? Причем по времени работы я сомневаюсь, что он будет быстрее
Если рассмотреть вариант для двух уровней:
Не вижу ничего страшного получать данные в двух запросах.
1) выбираем категории
SELECT * FROM `cat` WHERE `pid`=0
В цикле получаем массив категорий, а так же формируем переменную $ids вида "1, 3, 6, 23, 56, .."
2) получаем подкатегории
SELECT * FROM `cat` WHERE `pid` IN (_переменная_выше_)
Есть ли весомые причины городить один сложный запрос и его дополнительно обрабатывать? Причем по времени работы я сомневаюсь, что он будет быстрее
Спустя 1 час, 14 минут, 59 секунд (25.08.2010 - 01:53) ds837 написал(а):
Цитата |
Немного не хватает данных для вопроса: сколько уровней подкатегорий? |
до 5
Цитата |
Есть ли весомые причины городить один сложный запрос и его дополнительно обрабатывать? |
да очень большая база свыше 5000 тысяч категорий
Спустя 31 минута, 5 секунд (25.08.2010 - 02:24) Rivalryzerg написал(а):
Если такая большая база, то я полагаю есть условия выборки категорий? Не все же 5к выводить.
Если так, то есть смысл выбрать одним запросом сразу все категории, а уже в цикле обработки результата запроса разрулить все категории и подкатегории.
Смысл в том, чтобы верхние категории были в массиве $cats[0], а подкатегории в $cats[_ид_категории_родителя_].
Отображать рекурсивно.
PS: если где ошибся - завтра поправлю. сонный уже)
Если так, то есть смысл выбрать одним запросом сразу все категории, а уже в цикле обработки результата запроса разрулить все категории и подкатегории.
$cats = array();
$sql = "SELECT * FROM `cat` WHERE <условие>";
$res = $db->query($sql);
while ($row = $db->fetch($res)) {
$cats[$row['pid']][] = $row;
}
Смысл в том, чтобы верхние категории были в массиве $cats[0], а подкатегории в $cats[_ид_категории_родителя_].
Отображать рекурсивно.
PS: если где ошибся - завтра поправлю. сонный уже)
Спустя 10 часов, 20 минут, 43 секунды (25.08.2010 - 12:44) dr_Lev написал(а):
Введи дополнительно поле в таблицу cat, назови его например hist_index, в нем храни такую информацию : hist_index(родительской строки)+pid.
Таблица должна получиться такого типа :
id pid hist_index
1 0
2 1 -1-
3 1 -1-
4 2 -1-2-
5 3 -1-3-
6 4 -1-2-4-
7 6 -1-2-4-6-
8 5 -1-3-5-
Тогда SQL для выбора все подкатегорий с категории 2 :
Таблица должна получиться такого типа :
id pid hist_index
1 0
2 1 -1-
3 1 -1-
4 2 -1-2-
5 3 -1-3-
6 4 -1-2-4-
7 6 -1-2-4-6-
8 5 -1-3-5-
Тогда SQL для выбора все подкатегорий с категории 2 :
SELECT * FROM cat WHERE hist_index like '%-2-%'
Спустя 1 минута, 5 секунд (25.08.2010 - 12:45) dr_Lev написал(а):
Есть и другой вариант, делать JOIN столько раз, сколько уровней... но это геморно и несистемно...
Спустя 1 час, 57 минут, 16 секунд (25.08.2010 - 14:43) Rivalryzerg написал(а):
dr_Lev, не совсем понял зачем дополнительное поле в таблицу.
В любом случае запросы LIKE очень и очень медленные. Я бы не стал их использовать в данном случае.
Мой пример быстрее всего по скорости обработки запроса. Если будут проблемы с рекурсивным отображением - напишу пример.
В любом случае запросы LIKE очень и очень медленные. Я бы не стал их использовать в данном случае.
Мой пример быстрее всего по скорости обработки запроса. Если будут проблемы с рекурсивным отображением - напишу пример.
Спустя 2 часа, 29 минут, 14 секунд (25.08.2010 - 17:12) ds837 написал(а):
Спасибо! всем кто ответил
так и не смог вывести категорию и под категорию одним запросом без рекурсии
остановился на выводе в два запроса без рекурсии
сперва по pid вывожу родителей потом в цикле вывожу потомков
так и не смог вывести категорию и под категорию одним запросом без рекурсии
остановился на выводе в два запроса без рекурсии
сперва по pid вывожу родителей потом в цикле вывожу потомков
Спустя 16 минут, 28 секунд (25.08.2010 - 17:28) ds837 написал(а):
Цитата (Rivalryzerg @ 24.08.2010 - 23:24) |
$cats = array(); |
не знал что так можно красиво разложить в массив $cats[$row['pid']][] = $row; хороший пример пригодится, спасибо
Спустя 7 часов, 43 минуты, 26 секунд (26.08.2010 - 01:12) dr_Lev написал(а):
Цитата (Rivalryzerg @ 25.08.2010 - 14:43) |
dr_Lev, не совсем понял зачем дополнительное поле в таблицу. В любом случае запросы LIKE очень и очень медленные. Я бы не стал их использовать в данном случае. Мой пример быстрее всего по скорости обработки запроса. Если будут проблемы с рекурсивным отображением - напишу пример. |
ну не скажи... циклом бегать по массиву в РНР может оказаться намного медленнее... да и если не нравится LIKE, можно вставить LEFT :
SELECT * FROM cat WHERE LEFT(hist_index,5) = '-1-2-'