2016-07-07 111 views
5

Ho un problema complesso che sembra essere banale a prima vista:Quanti utenti attivi distinti ho avuto su una finestra di 90 giorni?

  • per una finestra determinata 90 giorni, il numero di utenti attivi distinti avevo?

La tabella userò per interrogare questo è la tabella di accesso (ospitato in Redshift), ed ha una data con il logintime e usertoken come l'identificativo utente.

Ogni volta che voglio rispondere a questa per un solo giorno, la query è semplice e lineare:

select count (distinct usertoken) 
from logins 
where datediff('d',logintime,getdate()) <= 90 

Il problema diventa complesso, perché voglio avere questo in una tabella con il numero per ogni determinata data.

07/07 100k 
07/06 98k 
07/05 99k 
07/04 101k 

(...)

funzioni della finestra non mi aiuti, perché ho bisogno di contare distinti, e questo non è possibile in una funzione finestra.

Per quanto ne so, non c'è modo di ripetere in una query SQL.

Come devo fare questo?

+0

Si prega di approfondire "ogni data". Passi il limite inferiore e superiore per l'intervallo di tempo? O una serie di date casuali? Possono esserci voci duplicate per un singolo utente nello stesso giorno? Quanto è grande il tuo tavolo? Numero di righe? Definizione di byte per riga/tabella. –

risposta

0

Il modo più banale è molto costoso computazionalmente:

select days.d, count(distinct l.userid) 
from (select distinct date_trunc('day', logintime) as d 
     from logins l 
    ) days left join 
    (select distinct userid, date_trunc('day', logintime) as d 
     from logins 
    ) l 
    on datediff('d', l.d, days.d) between 0 and 89 
group by days.d 
order by days.d; 
+0

Non devi dire 'tra 0 e 90' (o forse anche 89)? La differenza potrebbe essere negativa. – shawnt00

0

Forse mi manca qualcosa, ma da quanto ho capito questo dovrebbe fare:

- In SQL Server

select cast (logintime As Date), count (distinto usertoken) dagli accessi where datediff (D, logintime, getdate()) < = 90 Group by cast (login tempo come data)

in PostgreSQL Change cast (logintime come data) per trunc_Date (Giorno, logintime) e DateDiff (D, logintime, GETDATE()) per datediff ('d', logintime, GETDATE ())

0

Suppongo che se un giorno ha zero utenti che accedono a te non ti dispiace non mostrarlo nell'elenco.

Per prima cosa riceviamo un set di tutti i giorni che ci interessano e chiamiamo quel set di "giorni".

with days as (
    select date_trunc('day', date) as day from logins 
    where date > now() - '90 days'::interval 
    group by day 
    ) 

Quindi ci uniamo ai giorni impostati con gli accessi.

select day, count(distinct userid) 
from days 
join logins on date_trunc('day', logins.date) = days.day 
group by day 
order by day