PostgreSQL-获取统计数据
我需要在申请表中收集一些统计信息。 我有一个用户表(tb_用户) 每次新用户访问应用程序时,它都会在此表中添加一条新记录,即每个用户一行。主字段为id和日期(小时)(用户第一次访问应用程序的时间戳) tb\U用户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 我需要得到:
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