2017-11-01 5 views
1

Ich habe eine Tabelle mit Benutzerereignissen und eine andere Tabelle mit den Namen aller Ereignisse im System.Berechnung der Anzahl der Ereignisse pro Benutzer pro Ereignis, einschließlich der Anzahl von 0

Was ich brauche, ist pro-Ereigniszähler für jeden Benutzer, einschließlich Ereignisse, von denen sie 0.

Dialect hatte, ist ANSI SQL, unsicher Version. Die Datenbank ist Presto 0.186.

Hier ist ein Beispiel:

with 
event_names (name) as (values 
    ('event_1'), ('event_2'), ('event_3'), ('event_4') 
) 
, events (user_id, event_name, occurred_at) as (values 
    ('id1', 'event_1', timestamp '2017-10-10 00:01:00') 
    , ('id1', 'event_2', timestamp '2017-10-10 00:02:00') 
    , ('id1', 'event_2', timestamp '2017-10-10 00:03:00') 
    , ('id2', 'event_2', timestamp '2017-10-11 00:01:00') 
    , ('id2', 'event_3', timestamp '2017-10-11 00:02:00') 
    , ('id2', 'event_3', timestamp '2017-10-11 00:03:00') 
    , ('id2', 'event_4', timestamp '2017-10-11 00:03:00') 
    , ('id3', 'event_1', timestamp '2017-10-12 00:03:00') 
    , ('id3', 'event_4', timestamp '2017-10-12 00:04:00') 
) 

select user_id, event_name, count(*) as event_count, sum(count(*)) over (partition by user_id) as total_events 
from events 
group by 1, 2 
order by 1, 2; 

Diese Abfrage gibt mir natürlich nur die Zählungen für Veranstaltungen hat der Benutzer senden:

user_id | event_name | event_count 
---------+------------+------------- 
id1  | event_1 |   1 
id1  | event_2 |   2 

id2  | event_2 |   1 
id2  | event_3 |   2 
id2  | event_4 |   1 

id3  | event_1 |   1 
id3  | event_4 |   1 

Was ich brauche, ist die folgende:

user_id  | name | event_count 
-------------+---------+------------- 
id1   | event_1 |   1 
id1   | event_2 |   2 
id1   | event_3 |   0 
id1   | event_4 |   0 

id2   | event_1 |   0 
id2   | event_2 |   1 
id2   | event_3 |   2 
id2   | event_4 |   0 

id3   | event_1 |   1 
id3   | event_2 |   0 
id3   | event_3 |   0 
id3   | event_4 |   1 

Antwort

2

Generieren Sie alle Zeilen mit einem cross join. Dann bringt in den Daten, die vorhanden ist:

select u.user_id, en.event_name, count(e.user_id) as event_count, 
     sum(count(e.user_id)) over (partition by user_id) as total_events 
from (select distinct user_id from events) u cross join 
    (select distinct event_name from events) en left join 
    events e 
    on e.user_id = u.user_id and e.event_name = en.event_name 
group by 1, 2 
order by 1, 2; 

Wenn Sie andere Tabellen mit den Listen von Benutzern oder Ereignissen haben, dann können Sie diese anstelle der Unterabfragen verwenden.

Verwandte Themen