大家好。 我有一张表,列出了不同客户在不同日期的行为。 我需要对这些客户进行月度报告,但其中一列应包括账户不等于零的客户数量。
我的表看起来像这样:
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为零。
到目前为止,我只设法为数据添加时间戳。
我的问题是,如何在任何时间段内累计对每个客户的账户进行求和,并计算这些账户与零不同的个案数量?
答案 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
让我知道这是否有效。