Разбиение данных на категории

251
26 ноября 2017, 15:31

Есть структура данных в базе

product1   category2
product2   category1
product3   category1
product4   category3
....

Мне необходимо вывести эти данные в select и сгруппировать с помощью optgroup, чтобы по итогу было как то так

-category1
  --product2
  --product3
-category2
  --product1
-category3
  --product4

Я в целом смог сделать подобный вывод

                $STH = $DBH->query('SELECT * from product'); 
                $STH->setFetchMode(PDO::FETCH_ASSOC); 
                    $current_category = null;
                    while($row = $STH->fetch()) {   
                        if ($row["p_category"] != $current_category) {
                            $current_category = $row["p_category"];
                            echo "#{$current_category}";
                        }
                        echo "<p>{$row["p_name"]} </p>";
                    }

Но в данном случае я не могу управлять группой,чтобы заключить ее в <optgroup>, так как я отдельно управляю названиями продукта и названиями категорий, а как сделать,чтобы можно было заключить отдельные группы в <optgroup> ?

Answer 1

Достаточно сортировку добавить в запрос и дополнить условия вывода:

$STH = $DBH->query('SELECT * from product ORDER BY p_category, p_name'); 
$STH->setFetchMode(PDO::FETCH_ASSOC); 
$current_category = null;
echo '<select>';
while($row = $STH->fetch()) {  
    // новая группа 
    if ($row['p_category'] !== $current_category) {
        // предыдущую группу закрыть
        if ($current_category !== null) {
            echo '</optgroup>';
        }
        $current_category = $row['p_category'];
        echo '<optgroup label="' . $current_category . '">';
    }
    echo '<option value="' . $row['p_name'] . '">' . $row['p_name'] . '/option>';
}
// предыдущую группу закрыть
if ($current_category !== null) {
    echo '</optgroup>';
}
echo '</select>';
Answer 2

Если сгруппировать по категориям и воспользоваться GROUP_CONCAT для объединения продуктов для категории, то может получится что-то такое

$STH = $DBH->query('SELECT `p_category`, GROUP_CONCAT(p_name) as `products` 
                    FROM `product` 
                    GROUP BY `p_category`'
        ); 
$STH->setFetchMode(PDO::FETCH_ASSOC); 
while($row = $STH->fetch()) {           
    $current_category = $row["p_category"];
    $products = explode(',', $row["products"]); // <!---- в $products будет массив продуктов
    echo "#{$current_category}";
    // здесь в цикле можно пробежаться по $products  
    foreach ($products as $p_name) {
        echo "<p>$p_name</p>";
    }
}

в итоге в p_category - будет имя категории, а в products - будут через запятую перечислены имена продуктов. Это перечисление можно разбить через explode

Answer 3

Хотел было пойти спать, но когда увидел данный вопрос (даже с имеющимися рабочими ответами) - просто не смог. От чудовищной несправедливости - как будто весь мир сговорился и решил просто игнорировать само существование чудесной константы PDO::FETCH_GROUP, словно созданной специально для этой задачи.

Собсно решение с применением потрясающей константы PDO::FETCH_GROUP:

$STH = $DBH->query('SELECT `p_category`, `p_name` FROM `product`');
echo '<select>';
foreach($STH->fetchAll(PDO::FETCH_GROUP | PDO::FETCH_COLUMN) as $pcategory => $pnames) {
    echo "<optgroup label=\"$pcategory\">";
    foreach($pnames as $pname) {
        echo "<option value=\"$pname\">$pname</option>";
    }
    echo "</optgroup>";
}
echo '</select>';

P.S. если вдруг понадобятся какие-то другие штуки, кроме p_name, тогда надо будет заменить fetchStyle на PDO::FETCH_GROUP | PDO::FETCH_ASSOC - ну и соответственно изменить подстановку значения в html-строку.

READ ALSO
Не работает проверка на категории WordPress

Не работает проверка на категории WordPress

Мне нужно проверять категорию и все вложенные категории, если запись принадлежит одной из них (главной или дочерней) то выводить один шаблон...

241
Получить время простоя, timestamp (алгоритм)

Получить время простоя, timestamp (алгоритм)

У нас есть общая система управления заказами, заказами управляют операторы, операторы могут приходить\уходить когда им захочется, наша задача...

224
PHP спарсить значения из кода по url

PHP спарсить значения из кода по url

Пытаюсь получить отдельные значения по ссылке wwwwowhead

226
Помогите с выводом комментариев ( дерево )

Помогите с выводом комментариев ( дерево )

Есть массив, первый параметр id, второй parent id и текст

183