2017-10-05 10 views
1

Ich habe ein Problem mit SQL. Ich habe die folgende Tabelle:Rotation von Clients in 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') 

Ich möchte gerne Client-Rotation berechnen. Also für jeden Monat, für jeden Shop muss ich zählen, wie viele Kunden umgekrempelt sind, wie viele Kunden wie vor einem Monat geblieben sind. Ich kann nicht nur die Anzahl der Clients betrachten, sondern ich muss prüfen, ob der spezifische Name des Clients einen Monat zuvor erschienen ist. Alle Daten sehen so aus: "Jahr-Monat-15".

So würde Ich mag Tisch bekommen, wie folgt:

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) 

So zum Beispiel für abc-Shop nach dem ersten Monat 0 Kunden aufgewühlt, 2 Kunden blieben als Monat vor und 1 neuer Client gesendet wurde. Churned bedeutet, dass der Client gegangen ist.

Danke für Hilfe. Ich bin mit SQL Server 2014

EDIT: Ein weiteres Beispiel: Für diese Daten:

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') 

Ich sollte die folgende Tabelle erhalten:

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) 

Dies ist einfaches Beispiel mit nur einem Shop zur Klärung.

+0

definieren "aufgewühlt" bitte. – Tanner

+0

Diese Herren, die Client verlassen. –

Antwort

1

können Sie versuchen, diese

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

Sorry, aber es funktioniert nicht richtig. –

+0

Was ist das Problem? Ich habe es mit ersten und zweiten Beispieldaten getestet und es gibt für beide das korrekte Ergebnis zurück. Das einzige Problem ist, dass es eine zusätzliche Tagesreihe für den maximalen Tag zurückgibt. Aber es kann leicht gefiltert werden. –

+0

Anstelle von MONTH (T1.date) - 1 = MONAT (T2. [Datum]) sollte es DATEDIFF (MONAT, T1.date, T2. [Datum]) = -1 Aber ich hätte ein anderes Beispiel geben sollen. Mit dieser Modifikation funktioniert es perfekt. Thans! –