Как построить массив массивов в списке, сгруппированном по одному полю

У меня есть таблица из многих элементов с похожими данными, такими как:

ItemDetails

id name value item_id
1 Toy 10300 1
2 Toy2 10103 1
3 Title One 1
4 Toy 300 2
5 Price 103 2
6 Exp 2020 2

Я хотел бы использовать метод find с использованием CakePHP 2.x, который считывает все данные и группирует все элементы в массиве, отсортированные по значению item_id. Это массив с каждым элементом, содержащим массив всех значений, имеющих один и тот же элемент item_id. Таким образом, массив выглядит так:

Array
(
 [0] => Array
 (
 [0] => Array
 (
 [ItemDetail] => Array
 (
 [id] => 1
 [name] => Toy
 [value] => 10300
 [item_id] => 1
 )

 )

 [1] => Array
 (
 [ItemDetail] => Array
 (
 [id] => 2
 [name] => Toy1
 [value] => 103003
 [item_id] => 1
 )

 )

 [2] => Array
 (
 [ItemDetail] => Array
 (
 [id] => 3
 [name] => Title
 [value] => One
 [item_id] => 1
 )
 )
 )
 [1] => Array
 (

 [0] => Array
 (
 [ItemDetail] => Array
 (
 [id] => 4
 [name] => Toy
 [value] => 300
 [item_id] => 2
 )

 )

 [1] => Array
 (
 [ItemDetail] => Array
 (
 [id] => 5
 [name] => Price
 [value] => 300
 [item_id] => 2
 )


 )

 [2] => Array
 (
 [ItemDetail] => Array
 (
 [id] => 6
 [name] => Exp
 [value] => 2020
 [item_id] => 2
 )
 )
 )
)

Я пробовал несколько идей с группировкой, но он, кажется, уничтожает все значения полей, кроме первого, который он находит в таблице. Я действительно не хочу объединять данные, но группирую все с похожим item_id вместе в своем собственном массиве.

Может ли кто-нибудь указать мне в правильном направлении? Я хотел бы сделать это с помощью одного оператора find, чтобы я мог использовать paginate. Мне удалось сделать это с помощью повторных находок с условиями => id = (список ожидаемых item_id) и построить массив из результатов каждого вызова. Но похоже, что должен быть лучший способ.

1 ответ

Агрегация Sql и группа не помогут вам делать то, что вы хотите здесь. То, что вам нужно сделать, это нечто вроде:

Закажите свой результирующий набор sql item_id в своем запросе.

что-то вроде:

select id,
 name,
 value,
 item_id
from ItemDetails
order by item_id

шаг за шагом результата, отслеживая предыдущий item_id во временной переменной. Когда текущая строка item_id не соответствует предыдущей, тогда пришло время запустить новый элемент вашего внешнего массива.

Итак, что-то вроде:

$temp_item_id = -1;
$i = -1;
$result = array();
foreach($statement->fetchRow() as $row) {
 if ($row['item_id'] !== $temp_item_id) {
 ++$i;
 $result[$i] = array();
 }
 $temp_item_id = $row['item_id'];
 $result[$i][] = array('ItemDetail' => $row);
}

licensed under cc by-sa 3.0 with attribution.