Mysql Sum或Group concat基于不同的id

时间:2018-05-31 08:47:05

标签: mysql sql distinct aggregate-functions

我确定有人已经在某处问过这个问题,但似乎无法找到它。

在mysql中是否可以将sum或group concat(AGGREGATE FUNCTION)结合使用?

例子:我有一个订单产品,可以有很多选择和许多受益人。如何在一个查询(不使用子查询)中获取选项列表,期权价格和受益人列表?

我构建了一个示例数据集:

CREATE TABLE `order`
(id INT NOT NULL PRIMARY KEY);

CREATE TABLE order_product 
(id INT NOT NULL PRIMARY KEY
,order_id INT NOT NULL
);
CREATE TABLE order_product_options 
(id INT NOT NULL PRIMARY KEY
,title VARCHAR(20) NOT NULL
,price INT NOT NULL
,order_product_id INT NOT NULL
);

CREATE TABLE order_product_beneficiary 
(id INT NOT NULL PRIMARY KEY 
,name VARCHAR(20) NOT NULL
,order_product_id INT NOT NULL
);

INSERT INTO `order` (`id`) VALUES (1);
INSERT INTO `order_product` (`id`, `order_id`) VALUES (1, 1);
INSERT INTO `order_product_options` (`id`, `title`, `price`, `order_product_id`) 
VALUES  (1,'option1', 1, 1), (2, 'option2', 2, 1), (3, 'option3', 3, 1), (4, 'option3', 3, 1);

INSERT INTO `order_product_beneficiary` (`id`, `name`, `order_product_id`) 
VALUES  (1,'mark', 1), (2, 'jack', 1), (3, 'jack', 1);

http://sqlfiddle.com/#!9/37e383/2

我想要的结果是

  1. id:1
  2. 选项:option1,option2,option3,option3
  3. 期权价格:9
  4. 受益人:mark,jack,jack
  5. 在不使用子查询的情况下,这在mysql中是否可行? (我知道在甲骨文有可能) 如果可能的话,你会怎么做?

    由于

2 个答案:

答案 0 :(得分:1)

有点像,在内部查询中进行价格求和,然后加入order_product表。

SELECT 
    op.id,
    MAX(opo.title) AS 'options',
    MAX(opo.price) AS 'options price',
    GROUP_CONCAT(opb.name SEPARATOR ', ') AS 'beneficiaries'
FROM
    order_product op
INNER JOIN (
    SELECT order_product_id, SUM(price) price, GROUP_CONCAT(title SEPARATOR ', ') title
    FROM order_product_options
    GROUP BY order_product_id 
) opo ON opo.order_product_id = op.id
INNER JOIN order_product_beneficiary opb ON opb.order_product_id = op.id
GROUP BY op.id

Demo

答案 1 :(得分:1)

根据您的说明,我认为您只需要DISTINCT中的GROUP_CONCAT()。但是,由于重复(在评论中解释但不是问题),这将无效。

一种解决方案是在结果中包含ID:

SELECT op.id,
       GROUP_CONCAT(DISTINCT opo.title, '(', opo.id, ')' SEPARATOR ', ') AS options,
       SUM(opo.price) AS options_price,
       GROUP_CONCAT(DISTINCT opb.name, '(', opb.id, ')' SEPARATOR ', ') AS 'beneficiaries'
FROM order_product op INNER JOIN
      order_product_options opo
      ON opo.order_product_id = op.id INNER JOIN
      order_product_beneficiary opb 
      ON opb.order_product_id = op.id
GROUP BY op.id;

这不完全是你的结果,但它可能就足够了。

编辑:

哦,我明白了。您将加入两个不同的维度并获得笛卡尔积。解决方案是在加入之前聚合

SELECT op.id, opo.options, opo.options_price,
       opb.beneficiaries
FROM order_product op INNER JOIN
     (SELECT opo.order_product_id,
             GROUP_CONCAT(opo.title SEPARATOR ', ') AS options,
             SUM(opo.price) AS options_price
      FROM order_product_options opo
      GROUP BY opo.order_product_id
     ) opo
     ON opo.order_product_id = op.id INNER JOIN
     (SELECT opb.order_product_id,
             GROUP_CONCAT(opb.name SEPARATOR ', ') AS beneficiaries
      FROM order_product_beneficiary opb 
      GROUP BY opb.order_product_id
     ) opb
     ON opb.order_product_id = op.id;

Here是SQL小提琴。