【问题标题】:How to merge one to many in left join where right have multiple rows to single row如何在左连接中将一对多合并,其中右有多行到单行
【发布时间】:2020-04-19 11:19:29
【问题描述】:

您好,我在两张表中使用 leftjoin,一张是ordered_products,另一张是ordered_product_option

Ordered_produts 表:-

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

   1    Track Pants
   2    PT tshirt

ordered_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"
  ]

请提前帮助谢谢

【问题讨论】:

  • 按产品和连接选项数据分组。

标签: php mysql laravel laravel-5


【解决方案1】:

请考虑以下内容,它代表了使用 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,我喜欢根据数据类型将属性拆分为单独的表,这样你就有了一个整数类型的表和一个字符串类型的表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-27
    • 2020-04-27
    • 2018-01-21
    • 1970-01-01
    • 1970-01-01
    • 2013-05-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多