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

如何在SQL中计算时间范围内的最大行数?,sql,postgresql,Sql,Postgresql,这是Postgresql中的表: mydb=# \d login_log Table "public.login_log" Column | Type | Modifiers -------------+--------------------------+----------- id | integer | login_start | timestamp

这是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 | 
某些行:

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
我需要一个SQL来计算在哪个时间范围内有最多的登录用户

通过上面的示例,结果是:

时间范围:
2015-03-19 13:10:00~2015-03-19 13:20:00

5个用户登录。(1,2,3,4,7)

使用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
最后,按降序排列,只选择最高值

(来自非Postgresql用户,因此某些详细信息可能是错误的…如果是这种情况,请发表评论,我将进行编辑!)

使用(动态构建它们)。他们提供了不少有用的建议。您只需要定义一个,它将为您提供整个交叉点。所以-你会得到这样的结果:

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...
*/ 
请参见工作示例: