【问题标题】:Sum of all rows prior to (and including) date on current row in MYSQLMYSQL 中当前行的日期之前(包括)日期之前的所有行的总和
【发布时间】:2015-10-22 10:47:43
【问题描述】:

重要的是要知道在查询期间日期是未知的,所以我不能硬编码一个“WHERE”子句。

这是我的桌子:

+-----------+----------+-------------+
| Date_ID   | Customer | Order_Count |
+-----------+----------+-------------+
| 20150101  | Jones    | 6           |
| 20150102  | Jones    | 4           |
| 20150103  | Jones    | 3           |
+-----------+----------+-------------+

这是所需的输出:

+-----------+----------+------------------+
| Date_ID   | Customer | SUM(Order_Count) |
+-----------+----------+------------------+
| 20150101  | Jones    | 6                |
| 20150102  | Jones    | 10               |
| 20150103  | Jones    | 13               |
+-----------+----------+------------------+

我的猜测是我需要使用变量或连接。

编辑:仍然无法足够快地获得它。很慢。

【问题讨论】:

  • 鉴于您的输入数据,我无法看到您期望如何获得所需的输出。
  • 你的数据集有多大,表上有哪些索引?
  • 对于任何不是 MySQL 的 RDBMS,您想要的输出都非常容易,因为不支持窗口函数。见stackoverflow.com/questions/21720073/…

标签: mysql sql cumulative-sum


【解决方案1】:

您可以采用的一种方法是使用子查询将所有订单汇总到当前订单为止。可能不是最快的方法,但它应该可以解决问题。

SELECT `Date_ID`, `Customer`, 
    (SELECT sum(b.`Order_Count`) 
    FROM tablename as b WHERE 
    b.`Date_ID` <= a.`Date_ID` AND
    a.`customer = b.`Customer`) 
FROM tablename as a

【讨论】:

  • 我的数据集很大,子查询超级慢。此外,我认为在您的示例中我需要一个 group by 子句,因为实际上有不同的客户名称。
  • 将客户添加到子查询中,但它确实不是很快,因为它需要重新计算每个元素的完整总和。索引应该会有所帮助。如果它仍然太慢,您可能需要考虑在 SQL 之外的程序中计算总和。
【解决方案2】:

试试这个查询;在不限制您操作的数据集的情况下,这很可能是您能做的最好的事情。它应该受益于索引(客户、日期 ID)。

select 
  t1.date_id, t1.customer, sum(t2.order_count)
from 
  table1 t1
left join 
  table1 t2 on t1.customer = t2.customer
           and t1.date_id >= t2.date_id
group by 
  t1.date_id, t1.customer;

Sample SQL Fiddle.

【讨论】:

    【解决方案3】:

    如果存在性能问题,请考虑类似以下的解决方案:

    SELECT * FROM ints;
    +---+
    | i |
    +---+
    | 0 |
    | 1 |
    | 2 |
    | 3 |
    | 4 |
    | 5 |
    | 6 |
    | 7 |
    | 8 |
    | 9 |
    +---+
    
    SELECT i,@i:=@i+i FROM ints, (SELECT @i:=0)n ORDER BY i;
    +---+----------+
    | i | @i:=@i+i |
    +---+----------+
    | 0 |        0 |
    | 1 |        1 |
    | 2 |        3 |
    | 3 |        6 |
    | 4 |       10 |
    | 5 |       15 |
    | 6 |       21 |
    | 7 |       28 |
    | 8 |       36 |
    | 9 |       45 |
    +---+----------+
    

    【讨论】:

    • 有潜力,但到目前为止,无论客户名称如何,这都会对所有 ID 进行求和...而且 group by 也不会影响它...每个客户都应该独立求和。
    • 嗯,我想这就是选择提供适当(具有代表性的)DDL / sqlfiddle 之间的区别。
    • 在 8.0.xx 中可能不允许在 SELECT 中使用 @ 赋值;使用“窗口”功能如果你有 8.0 或 10.2。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多