对于在任何平台上连接的用户,如何按月/年计算?

时间:2015-10-21 14:57:52

标签: postgresql postgresql-9.3

我有一个名为users的表,其中包含用户ID,以及一些表,如cloud_storage_acloud_storage_bcloud_storage_c。如果用户存在于cloud_storage_a中,则表示它们已连接到云存储a。用户也可以存在于许多云存储中。这是一个例子:

id      | address      | name      | created_at
--------------------------------------------------
123     | 23 Oak Ave   | Melissa   | 2014-05-12
333     | 18 Robson Rd | Steve     | 2015-01-20
421     | 95 Ottawa St | Helen     | 2015-02-10
555     | 12 Highland  | Amit      | 2015-05-17
192     | 39 Anchor Rd | Oliver    | 2015-08-25

cloud_storage_a

user_id | created_at
---------------------
 421    | 2015-03-05
 333    | 2015-02-01

cloud_storage_b

user_id | created_at
----------------------
 555    | 2015-07-20

cloud_storage_c

user_id | created_at
---------------------
 192    | 2015-08-26
 555    | 2015-08-01

在此示例中,用户555在05-2015注册但直到07-2015才添加云存储b,并加入云存储c 08-2015。我目前有一个查询来确定用户按月/年分组连接到每个云存储所需的平均天数:

SELECT CONCAT(t1."Month",'-',t1."Year") as "Month-Year", a_connection_date::int AS "Average Days to Connect to A", 
b_connection_date::int as "Average Days to Connect to B", c_connection_date::int as "Average Days to Connect to C"
from ( 
  SELECT extract(YEAR from u.created_at) as "Year", extract(MONTH from u.created_at) as "Month", 
  AVG(extract (day from c.created_at - u.created_at)) as a_connection_date
  FROM users u INNER JOIN cloud_storage_a c ON u.id=c.user_id
  GROUP BY 1, EXTRACT(MONTH from u.created_at), EXTRACT(YEAR from u.created_at)
  order by "Year","Month") as t1
full join (SELECT extract(YEAR from u.created_at) as "Year", 
  extract(MONTH from u.created_at) as "Month", AVG(extract (day from 
  c.created_at - u.created_at)) as b_connection_date
  FROM users u INNER JOIN cloud_storage_b c ON u.id=c.user_id
  GROUP BY 1, EXTRACT(MONTH from u.created_at), EXTRACT(YEAR from u.created_at)
  order by "Year","Month"
) as t2
  on concat(t1."Year",'-',t1."Month")=concat(t2."Year",'-',t2."Month")
  full join (SELECT extract(YEAR from u.created_at) as "Year",     
  extract(MONTH from u.created_at) as "Month", AVG(extract (day from      
  c.created_at - u.created_at)) as c_connection_date
  FROM users u INNER JOIN cloud_storage_c c ON u.id=c.user_id
  GROUP BY 1, EXTRACT(MONTH from u.created_at), EXTRACT(YEAR from   u.created_at)
  order by "Year","Month"
) as t3
on concat(t1."Year",'-',t1."Month")=concat(t3."Year",'-',t3."Month")
ORDER BY t1."Year",t1."Month";

返回类似的内容:

Month-Year | Average Days to Connect to A | Average Days to Connect to B | Average Days to Connect to C 
---------------------------------------------------------------------------------------------------------
1-2015     | 11                           |                              |
2-2015     | 23                           |                              |                              
5-2015     |                              | 63                           | 73
8-2015     |                              |                              | 1

我还希望有一个列“连接到任何云的平均天数”(即对于用户555,他们在云c之前连接到云b,因此5-2015的平均天数将是63天而不是73.请注意,这个例子是一个小子集,因此可能有许多用户在5-2015注册并连接到各种云!

1 个答案:

答案 0 :(得分:1)

创建一个视图以容纳所有云存储:

create view all_cloud_storages as
select user_id, created_at from cloud_storage_a union
select user_id, created_at from cloud_storage_b union
select user_id, created_at from cloud_storage_c union
....
select user_id, created_at from cloud_storage_z;

然后更改"选择"你写了从新的"视图":

中检索记录
SELECT CONCAT(t1."Month",'-',t1."Year") as "Month-Year", 
       connection_date::int AS "Average Days to Connect to Any",
       first_connection_date as "Date of First Connection in Month",
       last_connection_date as "Date of Last Connection in Month"
FROM   ( 
         SELECT  extract(YEAR from u.created_at) as "Year", 
                 extract(MONTH from u.created_at) as "Month", 
                 AVG(extract (day from c.created_at - u.created_at)) 
                    as connection_date,
                 MIN(c.created_at) AS first_connection_date,
                 MAX(c.created_at) AS last_connection_date
           FROM  users u 
           INNER JOIN all_cloud_storages c ON u.id=c.user_id
           GROUP BY 1, 
                    EXTRACT(MONTH from u.created_at), 
                    EXTRACT(YEAR from u.created_at)
           order by "Year","Month"
       ) as t1
 ORDER BY t1."Year",t1."Month";