2017-02-28 12 views
0

ハローの皆さん。 私は、顧客ごとに顧客の行動が異なるテーブルを異なる日付で持っています。 私はこれらの顧客の月次レポートを作成する必要がありますが、列の1つにゼロ以外のアカウントを持つ顧客の数を含める必要があります。コードからの出力が第二に、顧客5用異なる日の累積合計数

Timestamp  #Customers with sum(Amount)<>0 
1    3 
2    2 
すべての3のためのアカウントが最初の期間中に正であるので

が、ゼロであるべき

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 

私のテーブルには、次のようになります期間。

これまで私はデータのタイムスタンプを管理していました。

私の質問は、どのようにして各顧客のアカウントを任意の時間枠で累計し、これらのアカウントがゼロと異なるケースの数を数えることができますか?あなたはgroup by句を使用することを検討すべきである

+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

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

が、この作品なら、私に教えてください。

1

別のオプションです。

内部サブクエリを使用してユニークなタイムスタンプを取得します(これらのテーブルがあれば、効果的にインデックスを効果的に使用できます)。これはテーブルに結合され、その日または前のすべての行が取得され、合計値が負の値を除外するためにHAVINGを使用してSUMが加算されます。

次に、外部クエリは、内部クエリの各タイムスタンプに対して返される顧客の数をカウントします。これは闘争かもしれない

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