Reputation: 163
I have my data as below:
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
I want to extract minimum value per window. i.e. I want my output as
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
I am trying to do something like this:
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
But I am not able to capture
1.2.3.4 abc 08:00
Any clue?
Upvotes: 1
Views: 48
Reputation: 16377
This answer is not as good as the one posted, but it's inspired by the first question I ever asked on Stack Overflow and wanted to pass on the tribute:
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
Upvotes: 1
Reputation: 37472
Use lag()
to check if a record is the first of a "group".
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;
Upvotes: 2