我有一个存储
的数据库模型我需要在一段时间范围内(比如说晚上8点到晚上9点)建立一个在线人员图表。我认为x轴是y轴作为人数的时间。图表的粒度为1分钟,但我的数据粒度为5秒。
由于人们在晚上8点之前或之后访问,我不能只计算在线秒数值。
我在考虑加载在特定日期发现的所有记录并在内存中进行计算(我现在可能会这样做,然后只是稍后缓存派生值)但我想知道是否有更高效的方式是什么?
我想知道是否有一个特殊的SQL查询组,我可以做的就是让它工作。
编辑:这是我从另一个问题(Count Grouped Gaps In Time For Time Range)窃取的图形表示:P
|.=========]
|.=============]
|=========.======]
|===.=================.====]
|.=================.==========]
T 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6
条形图表示我存储的数据(访问时间,上次查看时间和在线秒数),我需要知道在特定点上有多少在线。在这个例子中,对于T = 0,数字是3,对于T = 9,数字是4)
问:我无法理解您的意思“但我的数据精确到5秒”,您每次访问存储了多少条记录?你能添加一些示例数据吗?答:每次访问只有一条记录。粒度为5秒意味着我存储了长达5秒的准确数据。
按要求提供样本数据:
id visit_time last_seen_time seconds_online
1 00:00:00 00:00:12 10
2 00:12:41 00:12:47 5
3 00:01:20 00:01:22 0
4 00:01:22 00:01:27 5
在这种特殊情况下,如果我在00:00:00在线绘制人物,那么会有一个人,直到00:00:15才有0人:
4|
3|
2| *
1|* *
-*****-******************-
答案 0 :(得分:0)
非常有趣且难以回答的问题,如果我们假设图表的间隔应该是按小时(例如从8.00到8.59),并且按分钟的粒度,我们可以通过提取此日期部分来利用问题(如果您正在使用postgresql使用的函数应该是EXTRACT),我也建议使用Commont Table Expressions。
然后我们可以建立一个CTE,以便在目标时间内每次访问的第一分钟和最后一分钟,例如:
SELECT CASE WHEN EXTRACT(hour FROM visit_time) = 8
THEN EXTRACT(minute FROM visit_time)
ELSE 0 END AS first_minute,
CASE WHEN EXTRACT(hour FROM last_seen_time) = 8
THEN EXTRACT(minute FROM last_seen_time)
ELSE 59 END AS last_minute
FROM visit_table
WHERE EXTRACT(hour FROM visit_time) <= 8 AND EXTRACT(hour FROM last_seen_time) >= 8
新访问开始或访问结束时访问者更改的次数,因此我们可以从第一次开始构建第二次CTE,以获得访问者所有分钟的列表。数字更改,让名为target
的第一个CTE,然后后者可以定义为:
SELECT first_minute AS minute
FROM target
UNION
SELECT last_minute AS minute
FROM target
UNION
也会消除重复。
最后,我们可以加入这两个表并统计访问者:
WITH target AS (
SELECT CASE WHEN EXTRACT(hour FROM visit_time) = 8
THEN EXTRACT(minute FROM visit_time)
ELSE 0 END AS first_minute,
CASE WHEN EXTRACT(hour FROM last_seen_time) = 8
THEN EXTRACT(minute FROM last_seen_time)
ELSE 59 END AS last_minute
FROM visit_table
WHERE EXTRACT(hour FROM visit_time) <= 8
AND EXTRACT(hour FROM last_seen_time) >= 8
), time_table AS (
SELECT first_minute AS minute
FROM target
UNION
SELECT last_minute AS minute
FROM target
)
SELECT time_table.minute, COUNT(*) AS Users
FROM target INNER JOIN
time_table ON time_table.minute BETWEEN target.first_minute
AND target.last_minute
GROUP BY time_table.minute
ORDER BY time_table.minute
你应该获得一张表,其中第一条记录包含第一分钟,在目标小时内,当至少有一个在线访问者时,有在线人数,然后你有一个记录每次更改的数量在线人员,随着变化的分钟和新的在线人数,您可以轻松地从中创建图表。
很抱歉,如果我无法测试此解决方案,但我希望无论如何它都能为您提供帮助。