我有一个表存储大量这样的记录:
Time UserName
10:30 John
10:40 John
10:45 John
11:05 Sara
11:07 John
11:08 Ned
11:09 Ned
但是我需要以某种方式跳过与之前记录中相同UserName
的记录,因此只有第一个UserName
的记录才会出现,如下所示:
Time UserName
10:30 John
11:05 Sara
11:07 John
11:08 Ned
如何在常规编程语言中执行此操作非常明显,但我无法理解如何在SQL中执行此操作。
答案 0 :(得分:3)
下面的查询使用“gap and islands”方法(a.k.a。“tabibitosan”方法)将具有相同username
的CONSECUTIVE行组合在一起。
这仅适用于所有时间都不同的情况(否则row_number()
的输出不确定);但如果时间并非完全不同,那么无论如何都没有“连续”名称的“自然”意义(在这种情况下,问题本身需要澄清)。
select min(time) as time, username from
(select time, username,
row_number() over (order by time) -
row_number() over (partition by username order by time) as gp
from inputs
)
group by username, gp
order by time;
inputs
是基表。
答案 1 :(得分:3)
我认为最简单的方法是使用lag()
:
select t.time, t.name
from (select t.*,
lag(name) over (order by time) as prev_name
from t
) t
where prev_name is null or prev_name <> name;
我认为这也是最好的表现。
答案 2 :(得分:1)
类似这样的事情
select t1.Time ,t1.UserName from
( select Time ,UserName
,ROW_NUMBER() OVER ( ORDER BY Time,UserName ) R from table) t1
join ( select Time ,UserName
,ROW_NUMBER() OVER ( ORDER BY Time,UserName ) R from table) t2
on t1.R = t2.R - 1
where t1.UserName <> t2.UserName;
答案 3 :(得分:1)
这适用于所有没有分析功能的DB:
select * from temp t1
where not exists ( select 1 from temp t2
where t2.UserName = t1.UserName
and t2.Time < t1.Time
and not exists (select 1 from temp t3
where t3.UserName != t2.UserName
and t3.Time > t2.Time
and t3.Time < t1.Time
)
) ;
内部查询确保在其他名称之前没有出现其他相同的名称。