Php 如何在左侧连接中将一对多合并,其中右侧将多行合并为一行

Php 如何在左侧连接中将一对多合并,其中右侧将多行合并为一行,php,mysql,laravel,laravel-5,Php,Mysql,Laravel,Laravel 5,大家好,我使用leftjoin来表示两个表,一个是ordered\u products,另一个是ordered\u products\u option 订购产品表:- _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _id | name _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 1 Track Pants 2 PT tshirt 订购产品选项表:- _ _ _ _ _ _

大家好,我使用leftjoin来表示两个表,一个是ordered\u products,另一个是ordered\u products\u option

订购产品表:-

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

   1    Track Pants
   2    PT tshirt
订购产品选项表:-

  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
  _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中帮助感谢考虑以下内容,这代表了使用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   |
+------------+-------------+--------+------+
也就是说,多个左连接没有问题;事实上,它可以稍微快一点:

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,我喜欢根据数据类型将属性拆分为单独的表,因此您有一个整数类型的表和一个字符串类型的表

考虑以下内容,这代表了使用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   |
+------------+-------------+--------+------+
也就是说,多个左连接没有问题;事实上,它可以稍微快一点:

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,我喜欢根据数据类型将属性拆分为单独的表,因此您有一个整数类型的表和一个字符串类型的表

按产品和concat选项数据分组。按产品和concat选项数据分组。