2016-07-28 17 views
1

Ich bin neu in SQL und würde gerne wissen, wie man eine Anfrage für diese Frage schreiben. Können sagen, wir haben diese Felder: date_created date_unsubscribed SubscriberIdNested SQL Query für die Anzahl der Monate

enter image description here

Wie eine SQL-Abfrage zu schreiben, die von Monat auflistet, wie viele Menschen in die Liste abonniert haben, aus der Liste unsubscribed, und wie viele Netz Abonnenten gab es (neue Abonnenten minus Abbesteller). Alles in einer einzigen Abfrage ...

+0

Ist dies MySql oder Oracle? –

Antwort

1

Hier ist eine Option conditional aggregation und union all:

select month(dt), 
     count(case when subscribe = 1 then 1 end) subscribecount, 
     count(case when subscribe = -1 then 1 end) unsubscribecountt, 
     sum(subscribe) overallcount 
from (
    select date_created as dt, 1 as subscribe 
    from yourtable 
    union all 
    select date_unsubscribed, -1 
    from yourtable 
    where date_unsubscribed is not null 
) t 
group by month(dt) 

Die Unterabfrage erstellt eine Liste der Daten mit einer Fahne für abonnieren oder abbestellen. Dann können Sie count mit case verwenden, um die entsprechende Anzahl von Abonnenten/Abmelden zu bestimmen.

SQL Fiddle Demo

1

Sie könnten eine Summe (Fall) (eine Summe mit Bedingungen) schreiben zu aggregieren - die date_created Spalte unter der Annahme ist nie null. Zum Beispiel:

ORACLE:

SELECT 
TO_CHAR(DATE_CREATED,'MM-YYYY') CREATE_MONTH 
,SUM(CASE WHEN date_unsubscribed is not null then 1 else 0 end) unsubscribed 
,SUM(CASE WHEN date_unsubscribed is null then 1 else 0 end) subscribed 
,COUNT(SUBSCRIBER_ID) 
FROM 
--YOURTABLENAME 
--WHERE 
--WHATEVER OTHER CONDITIONS YOU HAVE APPLY 
GROUP BY TO_CHAR(DATE_CREATED,'MM-YYYY') 

MYSQL:

SELECT 
    DATE_FORMAT(DATE_CREATED,'%m-%Y') CREATE_MONTH 
    ,SUM(CASE WHEN date_unsubscribed is not null then 1 else 0 end) unsubscribed 
    ,SUM(CASE WHEN date_unsubscribed is null then 1 else 0 end) subscribed 
    ,COUNT(SUBSCRIBER_ID) 
    FROM 
    --YOURTABLENAME 
    --WHERE 
    --WHATEVER OTHER CONDITIONS YOU HAVE APPLY 
    GROUP BY DATE_FORMAT(DATE_CREATED,'%m-%Y') 
1

Oracle Lösung

Hier ist eine Abfrage, die PIVOT-Operator, die genau für diese Art von erstellt wurde arbeiten und ROLLUP, um die Nettozahl zu erhalten. Dies dient nur zur Veranschaulichung; Ich gehe davon aus, dass das Jahr eine Benutzer- oder Anwendungseingabe ist (Bindevariable :year, für die Ausgabe auf 2015 gesetzt), und ich zeige die Zusammenfassung für Januar bis Juni.

with 
    test_data (date_created, date_unsubscribed, subscriber_id) as (
     select date '2015-05-10', null    , 330053448 from dual union all 
     select date '2015-04-28', null    , 330053457 from dual union all 
     select date '2015-05-10', null    , 330053466 from dual union all 
     select date '2015-04-28', null    , 220053475 from dual union all 
     select date '2015-04-28', date '2015-05-10', 330053484 from dual 
    ), 
    prep (type, val, mth) as (
     select 'Subscribed' , 1, extract(month from date_created)  from test_data 
      where extract(year from date_created)  = :year 
     union all 
     select 'Unsubscribed', -1, extract(month from date_unsubscribed) from test_data 
      where extract(year from date_unsubscribed) = :year 
    ) 
select nvl(type, 'Net Subscr') as description, 
     nvl(sum(jan), 0) as jan, nvl(sum(feb), 0) as feb, nvl(sum(mar), 0) as mar, 
     nvl(sum(apr), 0) as apr, nvl(sum(may), 0) as may, nvl(sum(jun), 0) as jun 
from prep 
pivot (
     sum(val) 
     for mth in (1 as jan, 2 as feb, 3 as mar, 4 as apr, 5 as may, 6 as jun) 
    ) 
group by rollup(type) 
order by case type when 'Subscribed' then 1 when 'Unsubscribed' then 2 else 3 end 
; 


DESCRIPTION   JAN  FEB  MAR  APR  MAY  JUN 
------------ ---------- ---------- ---------- ---------- ---------- ---------- 
Subscribed   0   0   0   3   2   0 
Unsubscribed   0   0   0   0   -1   0 
Net Subscr   0   0   0   3   1   0 

3 rows selected.