Как объединить один со многими в левом соединении, где справа есть несколько строк в одну строку - PullRequest
1 голос
/ 19 апреля 2020

Привет, поэтому я использую левое соединение для двух таблиц: одна - order_products, а другая - order_product_option

Таблица Ordered_produts: -

 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
  _id   |  name
 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

   1    Track Pants
   2    PT tshirt

Таблица order_product_options: -

  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
  _id   |  ordered_produts_id | name  | value_name
 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

   110    1                    size      32
   111    1                    color     yellow
   112    2                    size      25

Мой запрос: -

$this->orderProduct->leftjoin('ordered_product_options', 'ordered_products._id', '=', 'ordered_product_options.ordered_products__id')
                      ->join('orders', 'ordered_products.orders__id', '=', 'orders._id')

                        ->select(

                    'ordered_products._id as _id',
                    'ordered_products.price as total_amount',
                    'ordered_products.name as product_name',
                    'ordered_product_options.name as option name',
                    'ordered_product_options.value_name as option_value' 

                )->get()->toArray();

Результат: -

      431 => array:5 [▼
    "_id" => 665
    "total_amount" => 300.0
    "product_name" => "PT TSHIRT"
    "option name" => "Size"
    "option_value" => "30"
  ]
  432 => array:5 [▼
    "_id" => 665
    "total_amount" => 300.0
    "product_name" => "PT TSHIRT"
    "option name" => "Color"
    "option_value" => "Yellow"
  ]

Результат Я хочу: -

 431 => array:5 [▼
    "_id" => 665
    "total_amount" => 300.0
    "product_name" => "PT TSHIRT"
    "option name" => "Size","color"
    "option_value" => "30","yellow"
  ]

Пожалуйста, помогите Спасибо в Advace

1 Ответ

0 голосов
/ 19 апреля 2020

Рассмотрим следующее, которое представляет собой один из популярных подходов при работе с EAV:

DROP TABLE IF EXISTS products;

CREATE TABLE products
(product_id SERIAL PRIMARY KEY
,name VARCHAR(20) NOT NULL UNIQUE
);

INSERT INTO products VALUES
(1,'Track Pants'),
(2,'PT tshirt');

DROP TABLE IF EXISTS product_options;

CREATE TABLE product_options
(product_id INT NOT NULL
,attribute VARCHAR(12) NOT NULL
,value VARCHAR(12) NOT NULL
,PRIMARY KEY(product_id,attribute)
);

INSERT INTO product_options VALUES
(1,'size',32),
(1,'color','yellow'),
(2,'size',25);

SELECT p.*
     , MAX(CASE WHEN po.attribute = 'color' THEN value END) color
     , MAX(CASE WHEN attribute = 'size' THEN value END) size 
  FROM products p 
  LEFT 
  JOIN product_options po 
    ON po.product_id = p.product_id 
 GROUP 
    BY p.product_id;
+------------+-------------+--------+------+
| product_id | name        | color  | size |
+------------+-------------+--------+------+
|          1 | Track Pants | yellow | 32   |
|          2 | PT tshirt   | NULL   | 25   |
+------------+-------------+--------+------+

Тем не менее, нет ничего плохого в нескольких LEFT JOIN; на самом деле это может быть немного быстрее:

SELECT p.*
     , color.value color
     , size.value size
  FROM products p
  LEFT 
  JOIN product_options color
    ON color.product_id = p.product_id
   AND color.attribute = 'color'
  LEFT 
  JOIN product_options size
    ON size.product_id = p.product_id
   AND size.attribute = 'size';

   +------------+-------------+--------+------+
   | product_id | name        | color  | size |
   +------------+-------------+--------+------+
   |          1 | Track Pants | yellow | 32   |
   |          2 | PT tshirt   | NULL   | 25   |
   +------------+-------------+--------+------+

Кроме того, хотя и не всегда популярно, при использовании EAV мне нравится разбивать атрибуты на отдельные таблицы в соответствии с типом данных, поэтому у вас есть таблица целых чисел вещи типа, и таблица вещей типа строки.

...