简体   繁体   English

如何在SQL中使用时间范围计算最大行数?

[英]How do I count the max rows with the time range in SQL?

This is the table in Postgresql: 这是Postgresql中的表:

mydb=# \d login_log 
              Table "public.login_log"
   Column    |           Type           | Modifiers 
-------------+--------------------------+-----------
 id          | integer                  | 
 login_start | timestamp with time zone | 
 login_end   | timestamp with time zone | 

some rows: 一些行:

1 | 2015-03-19 10:00:00  | 2015-03-19 13:30:00
2 | 2015-03-19 10:20:00  | 2015-03-19 13:20:00
3 | 2015-03-19 13:00:00  | 2015-03-19 16:00:00
4 | 2015-03-19 13:10:00  | 2015-03-19 16:00:00
5 | 2015-03-19 14:30:00  | 2015-03-19 15:30:00
6 | 2015-03-19 15:00:00  | 2015-03-19 15:30:00
7 | 2015-03-19 12:00:00  | 2015-03-19 18:00:00

I need a SQL to count out in which time range there is the max logged users. 我需要一个SQL才能计算出在哪个时间范围内记录的最大用户数。

with the example above, the result is: 在上面的示例中,结果是:

in time range: 2015-03-19 13:10:00 ~ 2015-03-19 13:20:00 , 5 users logged in. (1, 2, 3, 4, 7) 时间范围: 2015-03-19 13:10:00 ~ 2015-03-19 13:20:00 :10: 2015-03-19 13:10:00 ~ 2015-03-19 13:20:00 :20: 2015-03-19 13:10:00 ~ 2015-03-19 13:20:00个用户登录。(1、2、3、4、7)

Use range types (construct them "on the fly"). 使用范围类型 (“动态”构造它们)。 They offer quite a few helpful functions and operators . 它们提供了许多有用的功能和运算符 You would only need to define a custom aggregate , which will provide you the overall intersection. 您只需要定义一个自定义聚合 ,即可为您提供整个交叉点。 So - you would end up with something like this: 所以-您最终将得到如下结果:

with common as (
  select (intersection(tsrange(login_start, login_end))) as period 
  from login_log 
)
select 
  -- common.period, 
  -- array_agg(id) 
  *
from common, login_log
WHERE tsrange(login_start, login_end) && common.period
-- GROUP BY common.period
/* 
for some reason, when uncommenting the "^--..." lines, 
and commenting the "*" one - sqlfiddle shows an empty result. 
Nevertheless it works on my local posgres...
*/ 

See the working example: http://sqlfiddle.com/#!15/0c9c6/10 请参见工作示例: http : //sqlfiddle.com/#!15/0c9c6/10

Find different timestamps of interest using UNION ALL, count number of active users at these timestamps: 使用UNION ALL查找感兴趣的其他时间戳,计算这些时间戳下的活动用户数:

select ts,
       (select count(*) from login_log t2
        where timestamps.ts between t2.login_start and t2.login_end) as count
from (select login_start as ts
      from login_log
      union all
      select login_end
      from login_log) as timestamps
order by count desc
fetch first 1 row only

Finally order descending and pick the highest value only! 最后,降序排列并仅选择最高值!

(From a non Postgresql user, so some details may be wrong... Please comment if that's the case and I'll edit!) (来自非Postgresql用户,因此某些详细信息可能是错误的...如果是这种情况,请发表评论,我将进行编辑!)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM