[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Вывод категорий одним запросом
ds837
Подскажите кто знает как можно вывести одним запросом категорию и под категорию
есть талица с полями 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) выбираем категории
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 = 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 :
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 очень и очень медленные. Я бы не стал их использовать в данном случае.

Мой пример быстрее всего по скорости обработки запроса. Если будут проблемы с рекурсивным отображением - напишу пример.

Спустя 2 часа, 29 минут, 14 секунд (25.08.2010 - 17:12) ds837 написал(а):
Спасибо! всем кто ответил
так и не смог вывести категорию и под категорию одним запросом без рекурсии

остановился на выводе в два запроса без рекурсии

сперва по pid вывожу родителей потом в цикле вывожу потомков

Спустя 16 минут, 28 секунд (25.08.2010 - 17:28) ds837 написал(а):
Цитата (Rivalryzerg @ 24.08.2010 - 23:24)
$cats = array();
$sql = "SELECT * FROM `cat` WHERE <условие>";
$res = $db->query($sql);
while ($row = $db->fetch($res)) {
$cats[$row['pid']][] = $row;
}

не знал что так можно красиво разложить в массив $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-'
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.