2017-05-08 1 views
0

Ich habe die folgende Abfrage monatliche kumulative Benutzer zählt zu erhalten:Erhalten kumulative monatliche zählen Benutzer basierend auf Benutzer-E-Mail

SELECT RTRIM(TO_CHAR(DATE_TRUNC('month', created_at), 'Month YYYY')) AS month, 
     SUM(COUNT(id)::int) OVER (ORDER BY DATE_TRUNC('month', created_at)) AS total, 
     SUM((email  like '%@domain%')::int) AS with_domain, 
     SUM((email not like '%@domain%')::int) AS without_domain 
FROM users 
GROUP BY DATE_TRUNC('month', created_at) 
ORDER BY DATE_TRUNC('month', created_at); 

Das Ergebnis ist wie folgt:

[ 
    {"month"=>"October 2015", "total"=>2, "with_domain"=>1, "without_domain"=>1}, 
    {"month"=>"December 2015", "total"=>6, "with_domain"=>4, "without_domain"=>0}, 
    {"month"=>"January 2016", "total"=>13, "with_domain"=>4, "without_domain"=>3}, 
    {"month"=>"February 2016", "total"=>15, "with_domain"=>2, "without_domain"=>0}, 
    {"month"=>"March  2016", "total"=>36, "with_domain"=>15, "without_domain"=>6}, 
] 

See, wie total Zählung kumulativ und andere nicht?

Ich habe versucht, die folgende Abfrage:

SELECT RTRIM(TO_CHAR(DATE_TRUNC('month', created_at), 'Month YYYY')) AS month, 
     SUM(COUNT(id)::int)     OVER (ORDER BY DATE_TRUNC('month', created_at)) AS total, 
     SUM((email  like '%@domain%')::int) OVER (ORDER BY DATE_TRUNC('month', created_at)) AS with_domain, 
     SUM((email not like '%@domain%')::int) OVER (ORDER BY DATE_TRUNC('month', created_at)) AS without_domain 
FROM users 
GROUP BY DATE_TRUNC('month', created_at) 
ORDER BY DATE_TRUNC('month', created_at); 

Aber es wirft

column "users.email" must appear in the GROUP BY clause or be used in an aggregate function LINE 3: SUM((email like '%@domain%')::int) OVER (ORDER BY...^: SELECT RTRI 

und das Hinzufügen von email-GROUP BY Klausel überhaupt keinen Sinn macht ...

Wie kann ich alles machen kumuliert (wie es mit total getan wird)?

Erwartetes Ergebnis ist wie

[ 
    {"month"=>"October 2015", "total"=>2, "with_domain"=>1, "without_domain"=>1}, 
    {"month"=>"December 2015", "total"=>6, "with_domain"=>5, "without_domain"=>1}, 
    {"month"=>"January 2016", "total"=>13, "with_domain"=>9, "without_domain"=>4}, 
    {"month"=>"February 2016", "total"=>15, "with_domain"=>11, "without_domain"=>4}, 
    {"month"=>"March  2016", "total"=>36, "with_domain"=>26, "without_domain"=>10}, 
] 
+0

Ihr Fehler ist, dass Sie für die laufende Summe zu erhalten '(E-Mail [not] like‚% @ domain% versuchen, ') :: int' anstatt für 'SUM (email [nicht] wie'% @ domain% ') :: int)'. –

Antwort

1

wiederholen Sie einfach die Fenster Klauseln für jede Version Sie gesammelt werden sollen:

SELECT RTRIM(TO_CHAR(DATE_TRUNC('month', created_at), 'Month YYYY')) AS month, 
     SUM(COUNT(id)::int) OVER (ORDER BY DATE_TRUNC('month', created_at)) AS total, 
     SUM(SUM((email  like '%@domain%')::int)) OVER (ORDER BY DATE_TRUNC('month', created_at)) AS with_domain, 
     SUM(SUM((email not like '%@domain%')::int)) OVER (ORDER BY DATE_TRUNC('month', created_at)) AS without_domain 
FROM users 
GROUP BY DATE_TRUNC('month', created_at) 
ORDER BY DATE_TRUNC('month', created_at); 
+0

Könntest du mir bitte zeigen, wie man das aufräumt, um nicht zu wiederholen '(ORDER BY DATE_TRUNC ('month', created_at)) 'dreimal? –

+1

@AndreyDeineko [Sie können Ihre Fensterdefinition benennen] (https://www.postgresql.org/docs/current/static/sql-select.html#SQL-WINDOW) & verwenden Sie die' OVER window_name' Syntax. – pozs

0

basierend auf OP neu geschrieben

Verwendung Fensterfunktionen mit, um Kommentare für die Ruhe als auch aggs. wenn Sie auch gleiche Fenster verwenden, wobei es besser aus Hauptteil wie hier:

SELECT distinct RTRIM(TO_CHAR(DATE_TRUNC('month', created_at), 'Month YYYY')) AS month, 
     SUM(COUNT(id)::int) OVER w AS total, 
     SUM((email  like '%@domain%')::int) OVER w AS with_domain, 
     SUM((email not like '%@domain%')::int) OVER w AS without_domain 
     , DATE_TRUNC('month', created_at) --added for sorting 
FROM users 
WINDOW W AS (PARTITION BY DATE_TRUNC('month', created_at) ORDER BY DATE_TRUNC('month', created_at)) 
ORDER BY DATE_TRUNC('month', created_at); 
+0

Ich schrieb in meiner Frage, dass ich das versuchte und einen Fehler schrieb, den ich bekomme. Bitte gehen Sie über die Frage erneut –

+0

meine Abfrage ist anders - es hat keine Gruppe von. und Sie werden wahrscheinlich deutlich –

+0

ja wollen - es bedeutet, dass Sie die Spalte, die Sie für die Bestellung verwenden, auch ausgewählt werden müssen. Entweder entferne ich 'DATE_TRUNC ('month', created_at)' aus der Bestellung oder füge es zur Spaltenliste hinzu. –

1

die gruppierten Zählungen pro Monat und dann die laufende Summe erhalten.

SELECT month, 
     SUM(total) OVER (ORDER BY month) as total, 
     SUM(with_domain) OVER (ORDER BY month) AS with_domain, 
     SUM(without_domain) OVER (ORDER BY month) AS without_domain 
FROM (SELECT RTRIM(TO_CHAR(DATE_TRUNC('month', created_at), 'Month YYYY')) AS month, 
     COUNT(*) AS total, 
     SUM((email  like '%@domain%')::int) AS with_domain, 
     SUM((email not like '%@domain%')::int) AS without_domain 
     FROM users 
     GROUP BY RTRIM(TO_CHAR(DATE_TRUNC('month', created_at), 'Month YYYY')) 
     ) t 
ORDER BY month; 
+0

funktionierte auch, danke für eine Antwort! –

Verwandte Themen