2017-10-05 15 views
1

SQLに問題があります。私は次の表を持っています:SQL Serverのクライアントのローテーション2014

declare @t table (date datetime, 
      shop VARCHAR(50), 
      client VARCHAR(50) 
     ); 
insert into @t 
VALUES ('2016-01-15', 'abc','a1'), 
     ('2016-01-15', 'abc','b1'), 
     ('2016-01-15', 'def','c1'), 
     ('2016-01-15', 'def','a1'), 
     ('2016-01-15', 'ghi','b1'), 
     ('2016-01-15', 'ghi','a1'), 
     ('2016-02-15', 'abc','a1'), 
     ('2016-02-15', 'abc','b1'), 
     ('2016-02-15', 'abc','c1'), 
     ('2016-02-15', 'def','a1'), 
     ('2016-02-15', 'ghi','b1'), 
     ('2016-02-15', 'ghi','a1'), 
     ('2016-03-15', 'abc','a1'), 
     ('2016-03-15', 'abc','c1'), 
     ('2016-03-15', 'def','a1'), 
     ('2016-03-15', 'ghi','b1'), 
     ('2016-03-15', 'ghi','e1') 

私は、クライアントローテーションを計算したいと思います。だから毎月、どの店舗でも、私は何人の顧客が騒ぎ立てられたのか、何人の顧客が何ヶ月前に残っているのかを数えなければなりません。私はクライアント数を見ることはできませんが、クライアントの特定の名前が1か月前に現れたかどうかを確認する必要があります。すべての日付は「年 - 月-15」のようになります。

だから私は、次のようにテーブルを取得したいと思います:最初の月0クライアントが解約し

declare @t2 table (date date, 
       shop VARCHAR(50), 
       churned INTEGER, 
       stayed INTEGER, 
       came INTEGER 
      ); 

INSERT INTO @t2 
VALUES ('2016-02-15', 'abc', 0, 2, 1), 
    ('2016-02-15', 'def', 1, 1, 0), 
    ('2016-02-15', 'ghi', 0, 2, 0), 
    ('2016-03-15', 'abc', 1, 2, 0), 
    ('2016-03-15', 'def', 0, 1, 0), 
    ('2016-03-15', 'ghi', 1, 1, 1) 

だから、ABCショップのための例えば後に、2つのクライアントは、前の月のように滞在し、1つの新しいクライアントが来ました。 Churnedは、クライアントが残っていることを意味します。

ありがとうございました。私は、SQL Serverを使用しています2014

EDIT: もう一つの例:

declare @t table (date datetime, 
shop VARCHAR(50), 
client VARCHAR(50) 
    ); 
    insert into @t 
    VALUES ('2016-01-15', 'abc','a1'), 
    ('2016-01-15', 'abc','b1'), 

    ('2016-02-15', 'abc','b1'), 
    ('2016-02-15', 'abc','c1'), 

    ('2016-03-15', 'abc','z1'), 
    ('2016-03-15', 'abc','y1'), 
    ('2016-03-15', 'abc','a1') 

は、私は次の表を取得する必要があります:このデータについては は

declare @t2 table (date date, 
      shop VARCHAR(50), 
      churned INTEGER, 
      stayed INTEGER, 
      came INTEGER 
     ); 

    INSERT INTO @t2 
    VALUES 
    ('2016-01-15', 'abc', 0, 0, 2), 
    ('2016-02-15', 'abc', 1, 1, 1), 
    ('2016-03-15', 'abc', 2, 0, 3) 

これは一つだけと簡単な例であります明確化のために店。

+0

を定義してください試すことができます。 – Tanner

+0

クライアントが残したメンです。 –

答えて

1

あなたは "解約し、" この

SELECT 
    ISNULL(T1.date, DATEADD(MONTH,1,T2.date)) date, 
    ISNULL(T2.shop,T1.shop) shop, 
    COUNT(CASE WHEN T1.client IS NULL THEN 1 END) churned, 
    COUNT(case when (T1.client = T2.client) then 1 end) stayed, 
    COUNT(CASE WHEN T2.client IS NULL THEN 1 END) came 
FROM 
    @t T1 
    FULL JOIN @t T2 ON MONTH(T1.date) - 1 = MONTH(T2.[date]) 
      AND T1.client = T2.client AND T1.shop = T2.shop 
GROUP BY 
    ISNULL(T1.date, DATEADD(MONTH,1,T2.date)) ,ISNULL(T2.shop,T1.shop) 
ORDER BY [date], shop 
+0

申し訳ありませんが、正しく動作しません。 –

+0

問題は何ですか?私は第1および第2のサンプルデータでそれをテストし、それらの両方について正しい結果を返します。唯一の問題は、最大日後に追加の日の行を返すことです。しかし、簡単にフィルタリングすることができます。 –

+0

月(T1.date)の代わりに - 1 =月(T2。[日付]) DATEDIFF(MONTH、T1.date、T2。[日付])= -1しかし、別の例を挙げる必要があります。この変更により、完全に動作します。 Thans! –