【问题标题】:Create a Running Balance Total on Query with Union使用联合查询创建运行余额总计
【发布时间】:2016-12-01 15:31:40
【问题描述】:

我们有一个用于跟踪客户奖励积分的网络应用。我们正在使用 MySQL 数据库。 我最初有一个查询,它从单个表中提取数据并显示每个事务中的点数以及余额(RunningTotal),代码如下:

SELECT DateSubmitted
, PointTotal as Points
,   ( SELECT SUM( PointTotal ) 
        FROM ptrans_detail x 
            WHERE x.CustID = a.CustID
            AND ( x.DateSubmitted < a.DateSubmitted OR x.DateSubmitted = a.DateSubmitted) ) AS RunningTotal 
, comment 
   FROM ptrans_detail a 
    WHERE CustID='10009' 
    Order by TransID Desc

这工作正常,直到发现 ptrans_detail 表中不存在一些条目并且该问题已发布在这里: Query Data from 2 MySQL tables with some duplicate records

按照建议,我使用 UNION 组合来自 2 个表的 2 个查询来获取所有记录,该查询是:

SELECT CustID
      , DateSubmitted
      , Type
      , Points
          FROM `trans_summary`
            WHERE CustID = '10009'
UNION

SELECT CustID
, DateSubmitted
, Type
, PointTotal 
    FROM `ptrans_detail` 
       WHERE CustID = '10009'
            and DateSubmitted NOT IN 
           (SELECT DateSubmitted FROM 
             `trans_summary` 
              WHERE CustID = '10009')

效果很好,但现在我想在第一个查询中添加 RunningTotal。这可能吗?

【问题讨论】:

  • 当然,将整个语句视为一个子查询,并在 SELECT * FROM (您的联合查询此处)之外执行运行总计。还有,mysql和sql server是不同的数据库,你用的是哪个?
  • 嗨 Rich,我正在使用 MySQL。

标签: mysql sql


【解决方案1】:

你想要这个吗:

SELECT CustID, DateSubmitted, Type, SUM(Points) FROM (SELECT CustID
          , DateSubmitted
          , Type
          , Points
              FROM `trans_summary`
                WHERE CustID = '10009'
    UNION

    SELECT CustID
    , DateSubmitted
    , Type
    , PointTotal as Points
        FROM `ptrans_detail` 
           WHERE CustID = '10009'
                and DateSubmitted NOT IN 
               (SELECT DateSubmitted FROM 
                 `trans_summary` 
                  WHERE CustID = '10009')) AS tr_summery

【讨论】:

    【解决方案2】:

    我建议你使用union all,除非你真的需要union

    在 MySQL 中获得运行总和的最简单方法是使用变量:

    SELECT t.*,
           (@sump := if(@c = CustId, @sump + Points,
                        if(@c := CustId, Points, Points)
                       )
           ) as runningTotal
    FROM (SELECT CustID, DateSubmitted, Type, Points
          FROM trans_summary
          WHERE CustID = '10009'
          UNION ALL   -- Maybe it should be `UNION`
          SELECT CustID, DateSubmitted, Type, PointTotal 
          FROM ptrans_detail 
          WHERE CustID = '10009' AND
                DateSubmitted NOT IN (SELECT ts.DateSubmitted FROM trans_summary ts WHERE ts.CustID = '10009')
        ) t CROSS JOIN
        (SELECT @c := -1, @sump := 0) params
    ORDER BY CustId, DateSubmitted;
    

    【讨论】:

    • 嗯,有些记录在两个表中都是重复的,所以我只想显示一次,我的印象是使用 UNION 而不是 UNION ALL
    • 效果很好。我唯一的问题是我想按 DateSubmitted Desc 显示(最新记录优先)。但是,运行总计从最近的日期开始,并且总计返回...我如何才能将其反转,以便从最旧的 DataSubmitted 开始总计?
    • ORDER BY CustId, DateSubmitted DESC 解决问题了吗?
    猜你喜欢
    • 2012-07-03
    • 1970-01-01
    • 2016-07-18
    • 2017-06-11
    • 1970-01-01
    • 1970-01-01
    • 2014-06-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多