不同日期的累计金额

时间:2017-02-28 13:15:20

标签: mysql sql

大家好。 我有一张表,列出了不同客户在不同日期的行为。 我需要对这些客户进行月度报告,但其中一列应包括账户不等于零的客户数量。

我的表看起来像这样:

CustomerID      Timestamp   Amount  
5               1           100     
5               1           150
10              1           20
15              1           200
15              1          -150
5               2          -250     
10              2           50
10              2           50

代码的输出应为

Timestamp      #Customers with sum(Amount)<>0
1              3
2              2

由于所有3个账户在第一个期间均为正数,而在第二个期间为客户5为零。

到目前为止,我只设法为数据添加时间戳。

我的问题是,如何在任何时间段内累计对每个客户的账户进行求和,并计算这些账户与零不同的个案数量?

3 个答案:

答案 0 :(得分:2)

您可以使用相关的子查询获取运行总和,并获得每个时间戳的不同客户的数量,其中&lt;&gt; 0之后。

SELECT timestamp,
    COUNT(DISTINCT customerid) AS count_customer
FROM(
    SELECT customerid, 
        timestamp,
        (
            SELECT SUM(amount) 
            FROM tablename t2
            WHERE t2.customerid = t1.customerid 
            AND t2.timestamp <= t1.timestamp
        ) AS cum_total
 FROM tablename t1
) t 
WHERE cum_total <> 0
GROUP BY timestamp;

编辑:您可以尝试使用变量,看看它是否表现更好。

select timestamp,count(*) 
from (select customerid,timestamp
      ,case when @customer=customerid then @cumsum:=@cumsum+amount else @cumsum:=amount end as rsum
      ,@customer:=customerid
     from (select customerid,timestamp,sum(amount) as amount 
           from tablename 
           group by customerid,timestamp) t
     join (select @cumsum:=0,@customer:='') c
     order by customerid,timestamp
    ) t
where rsum<>0
group by timestamp

答案 1 :(得分:1)

另一种选择。

使用内部子查询来获取唯一的时间戳(如果你有一个这样的表,它可能会更有效率,因为它可以有效地使用索引)。这将连接到表以获取当天或之前的所有行,并使用HAVING来计算金额,以排除总和为负的那些行。

然后外部查询计算内部查询中每个时间戳返回的客户数量。

SELECT sub1.Timestamp, 
        COUNT(sub1.CustomerID) 
FROM 
( 
    SELECT sub0.Timestamp, a.CustomerID, SUM(a.Amount) AS amount_sum 
    FROM 
    ( 
        SELECT DISTINCT Timestamp 
        FROM amount_table 
    ) sub0 
    LEFT OUTER JOIN amount_table a ON sub0.Timestamp >= a.Timestamp 
    GROUP BY Timestamp, 
            CustomerID 
    HAVING amount_sum > 0 
) sub1 
GROUP BY Timestamp

如果这可能很困难,则返回一个时间戳为0的行,其中没有客户在该日期之前有正数。对你来说可能不是问题,但如果是: -

SELECT sub1.Timestamp, 
        SUM(IF(amount_sum > 0, 1, 0)) 
FROM 
( 
    SELECT sub0.Timestamp, a.CustomerID, SUM(a.Amount) AS amount_sum 
    FROM 
    ( 
        SELECT DISTINCT Timestamp 
        FROM amount_table 
    ) sub0 
    LEFT OUTER JOIN amount_table a ON sub0.Timestamp >= a.Timestamp 
    GROUP BY Timestamp, 
            CustomerID 
) sub1 
GROUP BY Timestamp

答案 2 :(得分:0)

您应该考虑使用group by子句

select Timestamp, count(customerID) as CustomersWithNonZeroAmount 
from tableName 
where Amount<>0 group by timestamp

让我知道这是否有效。