使用日期列和按日期分组连接三个不同的表

时间:2016-08-24 17:54:44

标签: sql postgresql date join

我目前正在使用三个不同的表,看起来像这样

用户:

user_id|createtime
-----------------------------
001     2016-07-20
002     2016-08-15
003     2016-08-05
004     2016-08-23

对象:

objc_id|createtime|user_id
-----------------------------
001     2016-07-20   001
002     2016-07-15   001
003     2016-08-05   002
004     2016-08-23   001
005     2016-08-19   003
006     2016-08-21   004
007     2016-08-22   004

事件:

event_id|createtime|objc_id
-----------------------------
001      2016-08-25   001
002      2016-08-26   004
003      2016-08-28   002
004      2016-08-27   005
005      2016-08-30   003

我已经制作了一些select语句,告诉我在特定日期创建了多少新用户,对象或事件:

select createtime, count(user_id) as new_user from 
user where createtime >= CURRENT_DATE - INTERVAL '30 days' group by
createtime;

select createtime, count(objc_id) as new_objc from 
object createtime >= CURRENT_DATE - INTERVAL '30 days' group by createtime;

select createtime, count (event_id) from 
event where createtime >= CURRENT_DATE - INTERVAL '30 days' 
group by createtime;

现在我想制作一个select语句,其中显示所有新对象,用户和事件的数量,并按创建时间对它们进行分组。

但是我无法得到解决方案。实现的目标看起来像这样:

createtime|new_user|new_objc|new_event
---------------------------------------
2016-07-15              1
2016-07-20    1         1
2016-07-22    
2016-07-24
2016-08-05    1         1
2016-08-15    1
2016-08-19              1
2016-08-21              1
2016-08-22              1
2016-08-23    1         1
2016-08-25                      1
2016-08-26                      1
2016-08-27                      1
2016-08-28                      1
2016-08-30                      1

...当然,对于一个组,某些日期可能会出现多次,因此计数将为1或更高。

目标是查看营销是否会增加新用户的数量,购买对象以及随着时间的推移参加活动(您需要事件的对象)。

有人为此提供解决方案,还是必须使用单独的结果表?

3 个答案:

答案 0 :(得分:0)

如果您不想使用您的查询,请尝试:

SELECT T1.createtime , COUNT(U.user_id) new_user ,
       COUNT(O.objc_id) new_objc , COUNT(E.event_id) new_event
FROM (((SELECT distinct createtime from user
        WHERE createtime >= CURRENT_DATE - INTERVAL '30 days'
        UNION
        SELECT distinct createtime from object
        WHERE createtime >= CURRENT_DATE - INTERVAL '30 days'
        UNION
        SELECT distinct createtime from event
        WHERE createtime >= CURRENT_DATE - INTERVAL '30 days'
        ) as T1 
        LEFT JOIN user U ON T1.createtime = U.createtime)
        LEFT JOIN object O ON O.createtime = T1.createtime)
        LEFT JOIN join event E ON E.createtime = T1.createtime)
GROUP BY T1.createtime ORDER BY T1.createtime;

答案 1 :(得分:0)

SELECT
    Createtime
    ,COUNT(DISTINCT user_id) as new_user
    ,COUNT(DISTINCT objc_id) as new_objc
    ,COUNT(DISTINCT new_event) as new_objc
FROM (
    SELECT Createtime, user_id, CAST(NULL AS INT) as objc_id, CAST(NULL as INT) as event_id
    FROM
       users
    WHERE createtime >= CURRENT_DATE - INTERVAL '30 days'
    UNION ALL
    SELECT Createtime, CAST(NULL AS INT) as user_id, objc_id, CAST(NULL as INT) event_id
    FROM
       object
    WHERE createtime >= CURRENT_DATE - INTERVAL '30 days'
    UNION ALL
    SELECT Createtime, CAST(NULL AS INT) as user_id, CAST(NULL AS INT) as objc_id, event_id
    FROM
       event
    WHERE createtime >= CURRENT_DATE - INTERVAL '30 days'
) t
GROUP BY
    Createtime
ORDER BY
    Createtime

当你第一次看到你的问题时,看起来你需要一个联接,但现实是你需要联合all和count()。我正在计算DISTINCT,这应该是多余的,因为user_id,objc_id,event_id似乎是唯一的主键。

答案 2 :(得分:-1)

将三个select语句用作扩展连接中的子查询。

SELECT A.createtime, A.new_user, B.new_objc, C.new_event 
FROM (
    select createtime, count(user_id) as new_user from 
    user where createtime >= CURRENT_DATE - INTERVAL '30 days' group by
    createtime;
) A INNER JOIN (
    select createtime, count(objc_id) as new_objc from 
    object createtime >= CURRENT_DATE - INTERVAL '30 days' group by createtime;
) B ON A.createtime = B.createtime INNER JOIN (
    select createtime, count (event_id) as new_event from 
    event where createtime >= CURRENT_DATE - INTERVAL '30 days' 
    group by createtime;
) C ON B.createtime = C.createtime