【问题标题】:Try to get a cumulative sum out of columns which I sum on the fly尝试从我即时求和的列中获取累积总和
【发布时间】:2015-05-05 14:26:22
【问题描述】:

我有一张下表 -

+------------------------------------------+
¦ date       ¦ earn_points ¦ redeem_points ¦
¦------------+-------------+---------------¦
¦ 2015-05-05 ¦ 50          ¦ 30            ¦
¦------------+-------------+---------------¦
¦ 2015-05-05 ¦ 60          ¦ 30            ¦
¦------------+-------------+---------------¦
¦ 2015-05-04 ¦ 70          ¦ 50            ¦
¦------------+-------------+---------------¦
¦ 2015-05-04 ¦ 80          ¦ 40            ¦
¦------------+-------------+---------------¦
¦ 2015-05-03 ¦ 30          ¦ 20            ¦
+------------------------------------------+

我正在寻找以下结果 -

+-------------------------------------------------------------------------------------------------------------+
¦ date       ¦ total_earn_points ¦ total_redeem_points ¦ total_liability_points ¦ Cumulative_liability_points ¦
¦------------+-------------------+---------------------+------------------------+-----------------------------¦
¦ 2015-05-05 ¦ 110               ¦ 60                  ¦ 50                     ¦ 120                         ¦
¦------------+-------------------+---------------------+------------------------+-----------------------------¦
¦ 2015-05-04 ¦ 150               ¦ 90                  ¦ 60                     ¦ 70                          ¦
¦------------+-------------------+---------------------+------------------------+-----------------------------¦
¦ 2015-05-03 ¦ 30                ¦ 20                  ¦ 10                     ¦ 10                          ¦
+-------------------------------------------------------------------------------------------------------------+

我正在尝试这个 SQL 查询,但无法获得正确的累计总数:

SELECT `transaction_date`, 
IFNULL(SUM(rewards_point_rewarded),0) AS `total_earn_points`, 
IFNULL(SUM(rewards_point_redemed),0) AS `total_redeem_points`, 
(SUM(rewards_point_rewarded) - SUM(rewards_point_redemed)) AS `total_liability_points`, 
@total := @total + (SUM(rewards_point_rewarded) - SUM(rewards_point_redemed)) AS `Cumulative_liability_points` 
FROM `i_report_total_order`, (SELECT @total:=0) AS t 
WHERE (website_id = '36') 
GROUP BY `transaction_date` 
ORDER BY `transaction_date` DESC

请帮助达到预期的结果。

【问题讨论】:

    标签: mysql cumulative-sum


    【解决方案1】:

    忽略 Alexandre 的评论,你显然已经尝试过了,构建了一个坚实的 qu,人们总是可以选择不回答。

    在 MySQL 中跨组使用 @ 变量进行累积实际上有点雷区。

    我会采取先获取非累积值,然后使用@变量找到解决方案的方法:

      SELECT date, 
             SUM(earn_points) AS tot_earn_pts, 
             SUM(redeem_points) AS tot_redeem_pts
        FROM i_report_total_order
    /* WHERE website_id = 36 */
    GROUP BY date 
    ORDER BY date DESC
    

    然后:

      SELECT date,
             tot_earn_pts,
             tot_redeem_pts,
             tot_earn_pts - tot_redeem_pts AS tot_liability_pts,
             @cum := @cum + tot_earn_pts - tot_redeem_pts AS cum_liability_pts
        FROM (   
          SELECT date, 
                 SUM(earn_points) AS tot_earn_pts, 
                 SUM(redeem_points) AS tot_redeem_pts
            FROM i_report_total_order
         /* WHERE website_id = 36 */
        GROUP BY date 
             ) tots
        JOIN (SELECT @cum := 0) init
    ORDER BY date      
    

    不幸的是,您必须再次包装它才能获得您指定的日期顺序。但您可以通过将列设置为 NOT NULL 来避免 IFNULLS

    SQLFiddle Example

    更新

    SELECT *
      FROM (
        SELECT date,
               tot_earn_pts,
               tot_redeem_pts,
               tot_earn_pts - tot_redeem_pts AS tot_liability_pts,
               @cum := @cum + tot_earn_pts - tot_redeem_pts AS cum_liability_pts
          FROM (   
            SELECT date, 
                   SUM(earn_points) AS tot_earn_pts, 
                   SUM(redeem_points) AS tot_redeem_pts
              FROM i_report_total_order
           /* WHERE website_id = 36 */
          GROUP BY date 
               ) tots
          JOIN (SELECT @cum := 0) init
      ORDER BY date  
           ) res_asc
    ORDER BY date DESC
    

    更新SQLFiddle

    【讨论】:

    • 我检查了你创建的小提琴。如果我通过 DESC 更改日期顺序,结果显示不正确。最新日期值应大于较早日期。
    • '不幸的是,您必须再次包装它才能获得您指定的日期顺序..',用户变量将按照查询指定的顺序进行评估..如果您将它们相加然后最后一行将是最大的。
    【解决方案2】:

    根据您的帮助,这是在我的案例中有效的查询

    SELECT `transaction_date`, 
           `total_earn_points`, 
           `total_redeem_points`, 
           `total_liability_points`, 
           @total := @total + `total_liability_points` AS `Cumulative_liability_points` 
           FROM (
                  SELECT `transaction_date`, 
                  SUM(rewards_point_rewarded) AS `total_earn_points`, 
                  SUM(rewards_point_redemed) AS `total_redeem_points`,
                  (SUM(rewards_point_rewarded) - SUM(rewards_point_redemed)) AS `total_liability_points`  
                  FROM `i_report_total_order` 
                  WHERE (website_id = '36') 
                  GROUP BY `transaction_date` 
                  ORDER BY `transaction_date` ASC
           ) tots 
    join (SELECT @total:=0) AS init 
    ORDER BY `transaction_date` ASC
    

    仅当我在最后一行设置 ASC 时它才有效。有没有办法在顶部显示最新日期。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-02
      • 1970-01-01
      • 1970-01-01
      • 2016-10-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多