2017-02-28 54 views
0

暈倒大家。 我在不同的日期有不同客戶的客戶行爲表。 我需要對這些客戶進行月度報告,但其中一列應包括賬戶數量不等於零的客戶數量。不同日子的累計和計數

我的表看起來是這樣的:

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

這不是一個累計總和,這是一個按組計數。 – Shadow

+0

您可以在@vkp的答案中使用查詢 –

回答

2

您可以通過相關子查詢獲得運行總和,並獲得每個時間戳的不同客戶的數量,其後總和爲<> 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:[email protected]+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 
+0

代碼運行,我確信它正在做正確的事情。不幸的是,它會在5分鐘後停止,因爲超過了允許的最長時間。這一定是由於您稱爲「tablename」的表格由5.960.000行組成。 那麼還有其他更有效的方法嗎? –

+0

查看使用變量獲取運行總和的編輯。檢查它是否更快。 –

0

你應該考慮使用group by條款

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

讓我知道這是否正常工作。

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