PostgreSQL-获取统计数据

PostgreSQL-获取统计数据,sql,postgresql,select,Sql,Postgresql,Select,我需要在申请表中收集一些统计信息。 我有一个用户表(tb_用户) 每次新用户访问应用程序时,它都会在此表中添加一条新记录,即每个用户一行。主字段为id和日期(小时)(用户第一次访问应用程序的时间戳) tb\U用户 id (bigint) | date_time (timestamp with time zone) 1 | 2012-01-29 11:29:50.359-03 2 | 2012-01-31 14:27:10.359-03 我需要得到:

我需要在申请表中收集一些统计信息。 我有一个用户表(tb_用户) 每次新用户访问应用程序时,它都会在此表中添加一条新记录,即每个用户一行。主字段为id日期(小时)(用户第一次访问应用程序的时间戳)

tb\U用户

id (bigint) | date_time (timestamp with time zone)
 1          |  2012-01-29 11:29:50.359-03
 2          |  2012-01-31 14:27:10.359-03
我需要得到:

日、周、月平均用户数量

例如:

日间:55.45

每周:XX.XX

月份:XX.XX

编辑:

我的最佳解决方案是:

WITH daily_count AS (SELECT COUNT(id) AS user_count FROM tb_user)
SELECT user_count, tbaux2.days, (user_count/tbaux2.days) FROM daily_count, 
    (SELECT EXTRACT(DAY FROM (t2.diff) ) + 1 AS days
     FROM
       (with tbaux AS(SELECT  min(date_time) AS min FROM tb_user)
       SELECT (now() - min) AS diff
       FROM tbaux) AS t2) AS tbaux2
GROUP BY user_count, tbaux2.days
但是这个解决方案只适用于提取物(天…周和月)不起作用

欢迎任何帮助

或者:

SELECT user_count, tbaux2.days, (user_count/tbaux2.days) AS userPerDay, ((user_count/tbaux2.days) * 7) AS userPerWeek, ((user_count/tbaux2.days) * 30) AS userPerMonth
编辑2:

根据@Bruno的回复,有一些考虑因素:

当我问这个问题时,实际上我要求一种按天、月和年选择数据的方法。我认为我发布的搜索和@Bruno改进的搜索应该被解释为平均“每天、每7天和每30天”而不是以天、周、月为单位。我相信,如果用这种方式来解释,就不会出现示例中引用的性别问题(下降10%)。我相信“每个”的方法是我现在需要的答案,所以我会在这个答案上签名

我建议作为职位的改进:

  • 结果中只考虑关闭日(不收集当天的用户,也不计算部门中的当天)
  • 结果是两个数字
  • 考虑每周和每月数据的新研究
谢谢。

您应该查看(最小值、最大值、计数、平均值),这与数据聚合密切相关。对于基于日期的聚合,这也很有用

例如,这将返回每天的行数:

SELECT date_trunc('day', date_time) AS day_start,
       COUNT(id) AS user_count FROM tb_user
    GROUP BY date_trunc('day', date_time);
WITH total_min_max AS (SELECT
        COUNT(id) AS total_visits,
        MIN(date_time) AS first_date_time,
        MAX(date_time) AS last_date_time,
    FROM tb_user)
SELECT total_visits/((last_date_time::date-first_date_time::date)+1) AS users_per_day
    FROM total_min_max
然后,您可以使用以下方法计算每日平均值:

使用
'week'
而不是day进行每周计数,依此类推(请参阅
date\u trunc
文档)

编辑:(以下评论:2012年1月5日之前(即6日之前)的平均值。)

(如果最近没有就诊,我会用
NOW()
替换
last\u date\u time
,以计算到现在为止的平均值,而不是最后一次就诊之前的平均值。)

然后,对于每日、每周和“每月”:

尽管如此,您从这些统计数据中得出的结论可能不是很好,特别是如果您想了解它是如何变化的


我也会将每天的数据标准化,而不是假设一个月有30天(如果不是每小时,因为并非所有的日子都有24小时)。假设你在2011年1月每天有10次访问,在2011年2月每天有10次访问。这意味着你在1月有310次访问,2月有280次访问。如果你不注意,你可能会认为你的访问人数下降了近10%,所以2月出现了一些问题,但事实并非如此。

我想你必须写一个查询这就计算了你的数据集的一个子集。谢谢你的回答。这不是我所需要的。这种搜索只返回平均值,只考虑有记录的日子。但是,我需要考虑整个时期。例如,考虑到用户已经访问了01 / 01 / 2012(MM/DD/YY)。另一个是2012年5月1日,您的示例中显示的平均值为“1”,但我需要一个搜索,考虑到未发生插入的01天到05天之间的范围,显示结果:0.4。有什么想法吗?为此,我将在CTE中使用
WHERE
子句(使用
中选择
)要使用
date\u time
限制日期范围,请使用
SUM
而不是
AVG
,并除以范围内的天数。我可以做一些更改:将daily\u count设置为(选择date\u trunc('day',date\u time)作为day\u start,将count(id)设置为tb\u user中的user\u count,其中按日期分组('day',date\u time))选择总和(用户计数)从daily_count;我不知道如何限制日期和计算天数。@vcltzac,我刚刚用一个例子编辑了我的答案。如果您不熟悉这种
WHERE
子句,我建议您阅读一些SQL教程,否则,您就没有必要尝试理解或编写更复杂的查询。但是开展这项研究不足以熟悉WHERE子句,因为它不是一个微不足道的条件。我编辑了我的问题并输入了我的部分解决方案。
WITH daily_count AS (SELECT date_trunc('day', date_time) AS day_start,
       COUNT(id) AS user_count
    FROM tb_user
       WHERE date_time >= DATE('2012-01-01') AND date_time < DATE('2012-01-06') 
    GROUP BY date_trunc('day', date_time))
SELECT SUM(user_count)/(DATE('2012-01-06') - DATE('2012-01-01')) FROM daily_count;
SELECT COUNT(id)/(DATE('2012-01-06') - DATE('2012-01-01'))
    FROM tb_user
       WHERE date_time >= DATE('2012-01-01') AND date_time < DATE('2012-01-06');
WITH total_min_max AS (SELECT
        COUNT(id) AS total_visits,
        MIN(date_time) AS first_date_time,
        MAX(date_time) AS last_date_time,
    FROM tb_user)
SELECT total_visits/((last_date_time::date-first_date_time::date)+1) AS users_per_day
    FROM total_min_max
WITH daily_avg AS (
    WITH total_min_max AS (SELECT
            COUNT(id) AS total_visits,
            MIN(date_time) AS first_date_time,
            MAX(date_time) AS last_date_time,
        FROM tb_user)
    SELECT total_visits/((last_date_time::date-first_date_time::date)+1) AS users_per_day
        FROM total_min_max)
SELECT
         users_per_day,
         (users_per_day * 7) AS users_per_week,
         (users_per_month * 30) AS users_per_month
    FROM daily_avg