【问题标题】:MySQL SUM of one column, DISTINCT of ID column一列的 MySQL SUM,ID 列的 DISTINCT
【发布时间】:2016-02-04 13:25:04
【问题描述】:

我正在尝试为我们的订单创建一份摘要报告,但在一次查询中提取我所需的所有数据时遇到问题。

我要提取的数据:

  • 小计 - 所有销售价格的总和
  • delivery total - 所有订单的总和 deliveryTotal
  • orders - DISTINCT orderIds 的 COUNT 个
  • 数量 - 所有订购数量的总和

Orders 表(在本例中进行了简化)

| orderId | deliveryTotal | total |
|---------|---------------|-------|
| 1       | 5             | 15    |
| 2       | 5             | 15    |
| 3       | 7.50          | 27.50 |

订单商品表

| orderItemId | orderId | productId | salePrice | quantity |
|-------------|---------|-----------|-----------|----------|
| 1           | 1       | 1         | 10        | 1        |
| 2           | 2       | 1         | 10        | 1        |
| 3           | 3       | 1         | 10        | 1        |
| 4           | 3       | 2         | 10        | 1        |

我目前提取此数据的查询是

SELECT
    SUM(i.salePrice * i.quantity) as subtotal,
    SUM(DISTINCT o.deliveryTotal) as deliveryTotal,
    COUNT(DISTINCT o.orderId) as orders,
    SUM(i.quantity) as quantity
FROM orderItems i
INNER JOIN orders o ON o.orderId = i.orderId

这会产生正确的小计、订单计数和数量总和。但是当我在 17.50 之后,交货总额返回为 12.50。如果我这样做SUM(o.deliveryTotal),它将返回 25。

编辑:期望的结果

| subtotal | deliveryTotal | orders | quantity |
|----------|---------------|--------|----------|
| 40.00    | 17.50         | 3      | 4        |

【问题讨论】:

  • 你能给SQL Fiddle吗?
  • @Sadikhasan 这里是sqlfiddle.com/#!9/02cb0/1
  • 更新了问题并获得了期望的结果
  • 此查询是否始终应用于整个表,或者您希望稍后添加GROUP BY
  • 始终是整个表(将有一个 where 语句用于在日期之间进行选择)但没有分组。

标签: mysql


【解决方案1】:

https://tiaashish.wordpress.com/2014/01/31/mysql-sum-for-distinct-rows-with-left-join/

这是一篇博客文章,它准确地展示了我正在寻找的内容。也许这也可以帮助其他人。

公式是这样的:

SUM(o.deliveryTotal) * COUNT(DISTINCT o.orderId) / COUNT(*)

【讨论】:

  • 这似乎确实是 OP 正在寻找的答案
  • 优秀,是我正在寻找的答案。
  • 也许我遗漏了一些东西,但这似乎给出了不正确的结果。答案应该是5 + 5 + 7.50 = 17.50,但这会返回(5 + 5 + 7.50 + 7.50) * 3 / 4 = 18.75
  • @ClintWinter,那么你可能有两行7.50,如果它添加了两次。
【解决方案2】:

由于连接,SUM(DISTINCT deliveryTotal) 聚合被应用于包含值 5, 5, 7.5, 7.5(不同的 5 + 7.5 = 12.5)的行集。

如果您只是这样做,您的SUM() 所作用的行会变得更加明显

SELECT o.*
FROM orderItems i
INNER JOIN orders o ON o.orderId = i.orderId

相反,您要求的是deliveryTotal 中所有值的SUM(),无论它们在与orderItems 的连接中的位置如何。这意味着您需要在不同的级别应用聚合。

由于您不打算稍后添加GROUP BY,因此最简单的方法是使用子选择,其目的只是在整个表中获取SUM()

SELECT
    SUM(i.salePrice * i.quantity) as subtotal,
    -- deliveryTotal sum as a subselect
    (SELECT SUM(deliveryTotal) FROM orders) as deliveryTotal,
    COUNT(DISTINCT o.orderId) as orders,
    SUM(i.quantity) as quantity
FROM orderItems i
INNER JOIN orders o ON o.orderId = i.orderId

通常不鼓励使用子选择,但不会对子选择造成显着的性能损失,这与使用连接的替代方法没有什么不同。无论如何,必须在与现有连接分开的聚合上进行计算。其他方法会在FROM 子句中放置一个子查询CROSS JOIN,这与我们在子选择中放置的相同。性能是一样的。

【讨论】:

  • (SQLfiddle 现在没有回复我发布验证结果,但我将它加载到我的测试数据库中,它确实有效)
【解决方案3】:

在内部选择中选择每个订单,然后总结

Select 
SUM(subtotal) as subtotal,
sum(deliveryTotal) as deliveryTotal,
count(1) as orders,
sum(quantity) as quantity
from (
SELECT 
    SUM(i.salePrice * i.quantity) as subtotal,
    o.deliveryTotal as deliveryTotal,
    SUM(i.quantity) as quantity
FROM orders o
INNER JOIN orderItems i ON o.orderId = i.orderId
group by o.orderId) as sub

【讨论】:

    【解决方案4】:

    以下查询结果正是您所需要的

    SELECT SUM(conctable.subtotal),
    SUM(conctable.deliveryTotal),
    SUM(conctable.orders),
    SUM(conctable.quantity) from  
    (SELECT SUM(i.salePrice * i.quantity) as subtotal,
        o.deliveryTotal as deliveryTotal,
        COUNT(DISTINCT o.orderId) as orders,
        SUM(i.quantity) as quantity
    FROM orderItems i
    JOIN orders o ON o.orderId = i.orderId group by i.orderid) as conctable;
    

    【讨论】:

      猜你喜欢
      • 2017-04-01
      • 1970-01-01
      • 2014-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-25
      • 2015-01-10
      • 1970-01-01
      相关资源
      最近更新 更多