Форумы портала PHP.SU » PHP » SQL и Архитектура БД » Как получить данные из связанных таблиц?

Страниц (1): [1]
 

1. Koc - 06 Сентября, 2017 - 21:02:32 - перейти к сообщению
Есть 3 таблицы:

1. Таблица с товаром (id, название, цена)
2. Таблица со свойствами (id, название)
3. Таблица для связи товара и свойства (id_товара, id_свойства, значение_свойства)

Помогите сделать запрос, чтобы получить все товары с их свойствами в таком виде:
PHP:
скопировать код в буфер обмена
  1.  
  2. (
  3.     [0] => Array
  4.         (
  5.             [id] => 10
  6.             [name] => Название товара
  7.             [свойства_товара] => Array (
  8.                                 [0] => Array
  9.                                         (
  10.                                                 [id_свойства] => 1
  11.                                                 [значение_свойства] => значение
  12.                                         )
  13.                                 [1] => Array
  14.                                         (
  15.                                                 [id_свойства] => 2
  16.                                                 [значение_свойства] => значение
  17.                                         )
  18.                         )
  19.         )
  20.  
  21.     [1] => Array
  22.         (
  23.             [id] => 11
  24.             [name] => Название товара
  25.             [свойства_товара] => Array (
  26.                                 [0] => Array
  27.                                         (
  28.                                                 [id_свойства] => 5
  29.                                                 [значение_свойства] => значение
  30.                                         )
  31.                         )
  32.         )
  33. )


Пробую через LEFT JOIN, но мне возвращается такой массив:
PHP:
скопировать код в буфер обмена
  1.  
  2. (
  3.     [0] => Array
  4.         (
  5.             [id] => 10
  6.             [name] => Название товара 10
  7.             [id_свойства] => 1
  8.             [значение_свойства] => значение_1
  9.         )
  10.                
  11.     [1] => Array
  12.         (
  13.             [id] => 10
  14.             [name] => Название товара 10
  15.             [id_свойства] => 2
  16.             [значение_свойства] => значение_2
  17.         )
  18.  
  19.     [2] => Array
  20.         (
  21.             [id] => 11
  22.             [name] => Название товара 11
  23.             [id_свойства] => 5
  24.             [значение_свойства] => значение_5
  25.         )
  26. )


То есть он один и тотже товар вставляет несколько раз в массив, если у товара несколько значений.

Заранее спасибо!
2. Мелкий - 06 Сентября, 2017 - 22:12:34 - перейти к сообщению
Koc пишет:
получить все товары с их свойствами в таком виде

На выбор в зависимости от СУБД:
- невозможно
- в принципе возможно, но вы сами не рады будете
- возможно условно внятными средствами
Два последних варианта по-прежнему будут требовать постпроцессинг данных. Возможно ли сэкономить ресурсы базы на этом относительно двух элементарных запросов с постпроцессингом - большой и очень спорный вопрос.
3. Koc - 06 Сентября, 2017 - 22:32:49 - перейти к сообщению
Мелкий пишет:

На выбор в зависимости от СУБД:
- невозможно
- в принципе возможно, но вы сами не рады будете
- возможно условно внятными средствами
Два последних варианта по-прежнему будут требовать постпроцессинг данных. Возможно ли сэкономить ресурсы базы на этом относительно двух элементарных запросов с постпроцессингом - большой и очень спорный вопрос.


Проще тогда вытянуть в начале все товары, а потом в цикле для каждого товара вытянуть все его свойства?
Или о каких двух элементарных запросах вы говорите?
4. Мелкий - 07 Сентября, 2017 - 10:12:33 - перейти к сообщению
псевдокодом
PHP:
скопировать код в буфер обмена
  1. select /**/ from products
  2. foreach ($response as $row) {
  3.     $result[ $row['id'] ] = $row;
  4. }
  5. select /**/ from attributes where product_id in array_keys($result)
  6. foreach ($response as $row) {
  7.     $result[ $row['product_id'] ]['attributes'][] = $row;
  8. }
  9. return $result;
5. Koc - 08 Сентября, 2017 - 02:10:20 - перейти к сообщению
Мелкий пишет:
псевдокодом
PHP:
скопировать код в буфер обмена
  1. select /**/ from products
  2. foreach ($response as $row) {
  3.     $result[ $row['id'] ] = $row;
  4. }
  5. select /**/ from attributes where product_id in array_keys($result)
  6. foreach ($response as $row) {
  7.     $result[ $row['product_id'] ]['attributes'][] = $row;
  8. }
  9. return $result;


Большое спасибо, то что надо)
6. LIME - 08 Сентября, 2017 - 18:18:49 - перейти к сообщению
Мелкий, а не проще/лучше использовать постпроцесс после join?
С одной стороны передаем больше данных, с другой делаем один запрос. Есть определенный ответ или зависит от частностей?
Опять же можно обойтись без вложенных массивов вообще, если например проверять в цикле шаблона соответствие прошлого product_id текущему.
7. Мелкий - 08 Сентября, 2017 - 21:22:19 - перейти к сообщению
Зависит от частностей. То есть брать и измерять с конкретными распределениями данных.
8. LIME - 08 Сентября, 2017 - 22:00:11 - перейти к сообщению
Почему-то я так и думал)
На самом деле просто хотел показать тс варианты
На практике использую чаще приведенный способ с небольшим отличием
Формирую индексный массив ибо имею дело с объектами , а писать в необъявленное свойство не есть гуд
Хотя не стесняюсь делать запрос на каждое значение
Оптимизацию оставляю на потом

 

Powered by ExBB FM 1.0 RC1