【发布时间】:2016-02-01 09:57:01
【问题描述】:
我有一个包含时间戳列和多个标识符列的数据集。当按时间戳排序时,我想将具有相同标识符的相邻行的每个“块”压缩为一行。每个区块的最小和最大时间戳是必需的。
源数据:
TSTAMP ID1 ID2
t1 A B <= start of new block
t2 A B
t3 C D <= start of new block
t4 E F <= start of new block
t5 E F
t6 E F
t7 A B <= start of new block
t8 G H <= start of new block
期望的结果:
MIN_TSTAMP MAX_TSTAMP ID1 ID2
t1 t2 A B
t3 t3 C D
t4 t6 E F
t7 t7 A B
t8 t8 G H
我认为这对于一个窗口分析函数来说已经成熟了,但是如果不将 IDn 的所有相等组合分组,我就无法进行分区——而不仅仅是相邻行中的那些,当按时间戳排序时。
一种解决方法是首先在一个内联视图中创建一个键列,我稍后可以按该键进行分组,即块中的每一行具有相同的值,而每个块的值不同。我可以使用 LAG 分析函数来比较行值,然后调用 PL/SQL 函数来返回序列的 nextval/currval 值(在此上下文中限制直接在 SQL 中调用 nextval/currval)。
select min(ilv.tstamp), max(ilv.tstamp), id1, id2
from (
select case when (id1 != lag(id1,1,'*') over (partition by (1) order by tstamp)
or id2 != lag(id2,1,'*') over (partition by (1) order by tstamp))
then
pk_seq_utils.gav_get_nextval
else
pk_seq_utils.gav_get_currval
end ident, t.*
from tab1 t
order by tstamp) ilv
group by ident, id1, id2
order by 1;
gav_get_xxx 函数只是从序列中返回 currval/nextval。
但我想只使用 SQL 并避免使用 PL/SQL(因为我也可以在 PL/SQL 中轻松编写它并从管道函数中输出结果行)。
有什么想法吗?
谢谢。
【问题讨论】:
标签: sql oracle gaps-and-islands