2016-08-15 3 views
0

Ich habe 2 Tabellen (Benutzer, Logins). Ich möchte eine Abfrage erstellen, die Benutzer abruft, die im April einen create_date-Benutzer und einen creates_date-Benutzernamen haben. Dann würde ich gerne sehen, wie viele dieser Benutzer ein Login create_date im Mai haben. (Anmelden Cohort)Login-Kohorte über Monate

User_id | create_date 

    1 | 04-05-16 

    2 | 04-08-16 

    3 | 05-05-16 

    4 | 05-06-16 

User_id | login_create_date 

    1 | 04-05-16 

    1 | 05-08-16 

    1 | 05-09-16 

    2 | 04-09-16 

    2 | 05-015-16 

    3 | 05-16-16 

    3 | 05-20-16 

    3 | 05-21-16 

Antwort

1

Hier wird ein Verfahren exists mit:

select count(*) as April_Creates, 
     sum(case when exists (select 1 
          from logins l2 
          where l2.user_id = u.user_id and 
            l2.create_date >= '2016-05-01' and l2.create_date < '2016-06-01' 
          ) 
       then 1 else 0 
      end) as May_Logins 
from users u 
where u.create_date >= '2016-04-01' and u.create_date < '2016-05-01' and 
     exists (select 1 
       from logins l 
       where l.user_id = u.user_id and 
        l.create_date >= '2016-04-01' and l.create_date < '2016-05-01' 
      ); 

Eine alternative Methode verwendet bedingte Aggregation:

select sum(apr_login) as num_apr_logins, 
     sum(may_login) as num_may_logins, 
     sum(may_login)/1.0 * sum(may_login) as ratio 
from users u join 
    (select user_id, 
      max(case when l.create_date >= '2016-04-01' and l.create_date < '2016-05-01' 
         then 1 else 0 
       end) as apr_login, 
      max(case when l.create_date >= '2016-05-01' and l.create_date < '2016-06-01' 
         then 1 else 0 
       end) as may_login 
     from logins l 
     group by user_id 
     having apr_login = 1 
    ) l 
where u.create_date >= '2016-04-01' and u.create_date < '2016-05-01' ; 
+0

Sorry, ich möchte noch hinzufügen, dass die Datensätze in der Benutzer-Tabelle eindeutig sind, aber der Benutzer viele Instanzen in der Tabelle Anmeldungen haben. Wie würde ich mit Ihrer ersten Methode sicherstellen, dass nur einmal Benutzer gezählt werden? – Cletus

+0

@Cletus. . . Die erste Abfrage wählt nur aus der Tabelle "Benutzer" aus, sodass keine doppelten Benutzer vorhanden sein können. –

1

Ich bin ein Fan der Verwendung von LEFT JOIN und bedingter Aggregation anstatt sub/nested wählt für diesen Fall ...

SELECT 
    u.[User_id] 
    ,u.create_date 
    ,COUNT(CASE WHEN EXTRACT(MONTH FROM l.login_create_date) = 4 THEN 1 END) as AprilLoginsCreated 
    ,COUNT(CASE WHEN EXTRACT(MONTH FROM l.login_create_date) = 5 THEN 1 END) as MayLoginsCreated 
FROM 
    users u 
    LEFT JOIN logins l 
    ON u.[User_id] = l.[User_id] 
    AND EXTRACT(MONTH FROM l.login_create_date) IN (4,5) 
    AND l.login_create_date >= '2016-04-01' 
WHERE 
    EXTRACT(MONTH FROM u.create_date) IN (4) 
    AND u.create_date >= '2016-04-01' 
GROUP BY 
    u.[User_id] 
    ,u.create_date 
HAVING 
    COUNT(CASE WHEN EXTRACT(MONTH FROM l.login_create_date) = 4 THEN l END) > 1 

Also durch die Abfrage.

  • Join Benutzertabelle auf Logins, sondern nur die Anmeldungen, die im April & Mai
  • Verwenden Sie eine Case-Anweisung in der Aggregation zählen die Anzahl der Anmeldungen erstellt für April & Mai
  • verwenden die gleiche Bedingung geschaffen, in dem Aggregationsstatement für April in der having-Klausel, um die Datensätze auf diejenigen zu reduzieren, für die im April ein Benutzer und ein Login erstellt wurden.