简体   繁体   中英

Join on generate_series and count

I'm trying to find the # users who did action A or action B on a monthly basis.

Table: User - id - "creationDate"

Table: action_A - user_id (= user.id) - "creationDate"

Table: action_B - user_id (= user.id) - "creationDate"

The general idea of what I was trying to do was that I'd find the list of users who did action A in Month X and the list of users who did action B in Month X, then count how many ids are there for every month based on a generate_series of monthly dates.

I tried the following, however, the query times out when running and I'm not sure if there's any way to optimize it (or if it is even correct).

SELECT monthseries."Month", count(*)
FROM
  (SELECT to_char(DAY::date, 'YYYY-MM') AS "Month"
   FROM generate_series('2014-01-01'::date, CURRENT_DATE, '1 month') DAY) monthseries
LEFT JOIN
  (SELECT to_char("creationDate", 'YYYY-MM') AS "Month",
          id
   FROM action_A) did_action_A ON monthseries."Month" = did_action_A."Month"
LEFT JOIN
  (SELECT to_char("creationDate", 'YYYY-MM') AS "Month",
          id
   FROM action_B) did_action_B ON monthseries."Month" = did_action_B."Month"
GROUP BY monthseries."Month"

Any comments/ help would be immensely helpful!

If you want to count distinct users:

select to_char(month, 'YYYY-MM') as "Month", count(*)
from
    generate_series(
        '2014-01-01'::date, current_date, '1 month'
    ) monthseries (month)
    left join (
        (
            select distinct date_trunc('month', "creationDate") as month, id
            from action_a
        ) a
        full outer join (
            select distinct date_trunc('month', "creationDate") as month, id
            from action_b
        ) b using (month, id)
    ) s using (month)
group by 1
order by 1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM