【问题标题】:Find number of repeating visitors in a month - PostgreSQL查找一个月内重复访问者的数量 - PostgreSQL
【发布时间】:2014-07-10 02:54:40
【问题描述】:

我正在使用 PostgreSQL,我的数据看起来像这样:

UserID    TimeStamp
1          2014-02-03
2          2014-02-03
3          2014-02-03
1          2014-03-03
2          2014-03-03
6          2014-03-03
7          2014-03-03

这只是 2 天的虚拟数据,其中一些 UserID 在这两天都重复出现。我想知道每个月重复UserId 的次数。对于此示例,最终结果集应如下所示:

Count    Year    Month
0        2014    2
2        2014    3

在上表中,3014 年 3 月有 2 次重复 UserID,而 2014 年 2 月则没有。 我可以找出每个月不同的UserID,但找不到重复的UserID。在这方面的任何帮助将不胜感激。

【问题讨论】:

  • 仅从上个月或全年或以往重复?

标签: sql postgresql


【解决方案1】:
select
    count(distinct userid) as "Count",
    extract(year from t0.timestamp) as "Year",
    extract(month from t0.timestamp) as "Month"
from
    t t1
    inner join
    t t0 using (userid)
where t0.timestamp < date_trunc('month', t1.timestamp)
group by 2, 3

或者可能更快

select
    count(distinct userid) as "Count",
    extract(year from t0.timestamp) as "Year",
    extract(month from t0.timestamp) as "Month"
from t t1
where exists (
    select 1
    from t
    where
        userid = t1.userid
        and
        timestamp < date_trunc('month', t1.timestamp)
)
group by 2, 3

【讨论】:

    【解决方案2】:

    这可能有效,尚未测试。

    SELECT 
      COUNT(DISTINCT(UserId))
      , EXTRACT(YEAR FROM TIMESTAMP TimeStamp) AS Year
      , EXTRACT(MONTH FROM TIMESTAMP Timestamp) AS Month 
    FROM TABLE 
    GROUP BY TimeStamp
    

    【讨论】:

    • 这会给我一个月内唯一用户 ID 的数量,我想要每个月重复用户 ID 的数量
    【解决方案3】:

    重新表述您的问题:

    每个月有多少用户不是新用户(即在上个月已经访问过商店/网站/其他任何内容)?

    SELECT
       yr, mon,
       COUNT(*) AS all_users,
       COUNT(*) - SUM(repeated) AS new_users,
       SUM(repeated) AS existing_users
    FROM
     (
       SELECT UserId, 
          EXTRACT(YEAR FROM TimeStamp) AS yr,
          EXTRACT(MONTH FROM TimeStamp) AS mon,
          CASE WHEN ROW_NUMBER() -- 1st time users get 0
                    OVER (PARTITION BY UserId
                          ORDER BY EXTRACT(YEAR FROM TimeStamp) ,
                                   EXTRACT(MONTH FROM TimeStamp)) = 1 
               THEN 0 
               ELSE 1
          END AS repeated
       FROM vt
       GROUP BY UserId,
          EXTRACT(YEAR FROM TimeStamp),
          EXTRACT(MONTH FROM TimeStamp)
     ) AS dt
    GROUP BY yr,mon
    ORDER BY 1,2
    

    如果一个用户在同一个月内有多行,则需要内部 GROUP BY。

    【讨论】:

      【解决方案4】:

      这是你想要的吗?

      select yyyymm, sum(case when cnt > 1 then 1 else 0 end) as dupcnt
      from (select to_char(timestamp, 'YYYY-MM') as yyyymm, userid, count(*) as cnt
            from table t
            group by to_char(timestamp, 'YYYY-MM'), userid
           ) t
      group by yyyymm
      order by yyyymm;
      

      【讨论】:

      • 这个查询只给了我 0 和 1。我想要每个月重复 UserID 的总数
      • @Patthebug 。 . .这个查询应该返回每个月出现多次的用户 ID 总数,因为我已经修复了子查询中缺少的 userid 的语法错误。
      猜你喜欢
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 2020-06-16
      • 2016-10-29
      • 1970-01-01
      相关资源
      最近更新 更多