POSTGRESQL:提取每个窗口的最小值

时间:2018-12-18 01:02:13

标签: sql postgresql

我的数据如下:

 IP        username   time1  
-----      ------      -----  
1.2.3.4      abc      01:00  
1.2.3.4      abc      02:00  
1.2.3.4      abc      03:00  
1.2.3.4      pqr      04:00  
1.2.3.4      pqr      05:00  
1.2.3.4      pqr      06:00  
1.2.3.4      pqr      07:00  
1.2.3.4      abc      08:00  
1.2.3.4      abc      09:00  
1.2.3.5      abc      10:00  
1.2.3.5      abc      11:00  

我想提取每个窗口的最小值。即我希望我的输出为

IP        username   time1  
-----      ------      -----  
1.2.3.4      abc      01:00  
1.2.3.4      pqr      04:00  
1.2.3.4      abc      08:00  
1.2.3.5      abc      10:00  

我正在尝试执行以下操作:

select ip, usrnm, time1  
from (select ROW_NUMBER() over(partition by ip, usrnm order by time1)as 
rownum,ip, usrnm, time1 from table1)t2 
where t2.rownum = 1

但是我无法捕获

1.2.3.4 abc 08:00

有任何线索吗?

2 个答案:

答案 0 :(得分:2)

使用lag()检查记录是否是“组”中的第一条记录。

SELECT ip,
       username,
       time1
       FROM (SELECT ip,
                    username,
                    time1,
                    coalesce(lag(ip) OVER (ORDER BY time1) <> ip
                              OR lag(username) OVER (ORDER BY time1) <> username,
                             true) x
                    FROM elbat) x
       WHERE x;

db<>fiddle

答案 1 :(得分:1)

这个答案不如发布的答案,但它受到了我在Stack Overflow上问过的第一个问题的启发,并想通过致敬:

Oracle/Sybase SQL - get value based on a previous record (not a simple LAG)

with change_data as (
  select
    ip, username, time1,
    case
      when lag (username) over (partition by ip order by time1) = username
        then 0
      else 1
    end as newrecord
  from table1
),
groups as (
  select
    ip, username, time1,
    sum (newrecord) over (order by time1) as instance
  from change_data
)
select
  ip, username, min (time1) as min_time
from groups
group by
  ip, username, instance
order by
  min_time