Mysql只将一行求和一次 - 使用Group By

时间:2018-03-09 17:10:00

标签: mysql group-by sum distinct

我有一个看似简单的问题,我似乎无法解决。想象一下order表,其中包含该订单的运费值。想象一下item表指向订单,并且有价格:

顺序

 |id |created   |shipping|
 |---|----------|--------|
 |101|2018-01-01|10      |
 |102|2018-01-01|10      |

物品

 |order_id|price   |
 |--------|--------|
 |101     |1       |
 |101     |2       |
 |102     |3       |

所以有两个订单。每人的运费为10美元。一个订单有两个项目,价格为1美元和2美元。另一件有一件售价3美元。到目前为止非常简单。

我想写一个查询,它会找到每天的总运费和总项目价格(总和)(按created分组)。天真地,我会写这个查询:

SELECT 
    o.created, sum(o.shipping), sum(i.price)
FROM
    test_order o,
    test_item i
WHERE
    i.order_id = o.id
group by o.created

此查询非常简单。它连接两个表,然后group by该日期,并垂直求和。问题出在运输部分。由于加入后有三行,总和中有三个10美元的运费,这是完全错误的。

我可以在我的送货条款(distinct)中添加sum(distinct o.shipping),但这也是不正确的。它将评估这三个10,并且只保留一个,得到10美元的总和值。它没有认识到这些10中的两个来自一个源行,而第三个10来自完全不同的源行,并且希望将它包含在总和中。

我的真正的查询要复杂得多,但我将其简化为此。我认为这是许多用例的常见情况。当然,我可以写第二个查询(或子查询),但是如果可能的话,我不想这样做。

想亲自玩这些数据吗?这是sql:

CREATE TABLE IF NOT EXISTS `test_item` (
 `order_id` int(11) NOT NULL,
 `price` int(11) NOT NULL)
INSERT INTO `test_item` (`order_id`, `price`) VALUES (101, 1), (101, 2), (102, 3);

CREATE TABLE IF NOT EXISTS `test_order` (
 `id` int(12) NOT NULL,
 `created` datetime NOT NULL,
 `shipping` int(11) NOT NULL,
 PRIMARY KEY (`id`)
)
INSERT INTO `test_order` (`id`, `created`, `shipping`) VALUES (101, '2018-01-01 00:00:00', 10), (102, '2018-01-01 00:00:00', 10);

谢谢!

2 个答案:

答案 0 :(得分:1)

您正在尝试避免子查询,但在这种情况下,我无法看到其他选项:

<tr *ngFor="let change in changes">
    <td *ngFor="let col of _columns">
        <z-grid-cell-display [type]="change[col.displayType]" [field]="change" [context]="change[col.field]"></z-grid-cell-display>
    </td>
</tr>

Here小提琴。

答案 1 :(得分:0)

使用中间别名表可以解决问题:

select sumTable.createdDate, sum(sumTable.shippingSum),sum(sumTable.priceSum) from (
       SELECT 
       o.created, (o.shipping) as shippingSum, sum(i.price) as priceSum
       FROM
       test_order o,
       test_item i
       WHERE
       i.order_id = o.id
       group by o.created,o.id) 
as sumTable

我在SQL小提琴中over here进行了测试,得到了$30$6的总和,这可能是你想要的。