我的数据如下:
create table t (a varchar2(30), b date);
insert into t values (NULL,TO_DATE('2017/01/01 00:00:44', 'yyyy/mm/dd hh24:mi:ss'));
insert into t values (NULL,TO_DATE('2017/01/01 01:00:44', 'yyyy/mm/dd hh24:mi:ss'));
insert into t values ('AAAA',TO_DATE('2017/01/01 02:00:44', 'yyyy/mm/dd hh24:mi:ss'));
insert into t values (NULL,TO_DATE('2017/01/01 02:30:44', 'yyyy/mm/dd hh24:mi:ss'));
insert into t values ('AAAA',TO_DATE('2017/01/01 03:00:44', 'yyyy/mm/dd hh24:mi:ss'));
insert into t values (NULL,TO_DATE('2017/01/01 04:00:44', 'yyyy/mm/dd hh24:mi:ss'));
insert into t values ('AAAA',TO_DATE('2017/01/01 04:30:44', 'yyyy/mm/dd hh24:mi:ss'));
insert into t values (NULL,TO_DATE('2017/01/01 05:00:44', 'yyyy/mm/dd hh24:mi:ss'));
insert into t values ('AAAA',TO_DATE('2017/01/01 05:30:44', 'yyyy/mm/dd hh24:mi:ss'));
我需要为TEXT字段的每个重复模式分配一个组号。我正在寻找的模式是“AAAA - null - AAAA”。我希望能够忽略此模式之外的任何其他“空值”。实质上,希望分配这样的组号:
a b GROUP
(null) 1/1/2017 0:00 IGNORE FROM ASSIGNING GROUP #
(null) 1/1/2017 1:00 IGNORE FROM ASSIGNING GROUP #
AAAA 1/1/2017 2:00 1
(null) 1/1/2017 2:30 1
AAAA 1/1/2017 3:00 1
(null) 1/1/2017 4:00 IGNORE FROM ASSIGNING GROUP #
AAAA 1/1/2017 4:30 2
(null) 1/1/2017 5:00 2
AAAA 1/1/2017 5:30 2
我希望数据看起来像这样:
a b GROUP
AAAA 1/1/2017 2:00 1
(null) 1/1/2017 2:30 1
AAAA 1/1/2017 3:00 1
AAAA 1/1/2017 4:30 2
(null) 1/1/2017 5:00 2
AAAA 1/1/2017 5:30 2
Oracle SQL版本:
Oracle Database 11g 11.2.0.4.0 PL / SQL版本11.2.0.4.0
答案 0 :(得分:0)
假设:a
列中唯一可能的值为'AAAA'
和null
。 'AAAA'
值的数量可能是奇数(在这种情况下,最后一个值不会启动新组,它会被忽略,以及它之前和之后的所有null
行。列b
中没有重复的日期时间。
有了这些假设:首先,我们使用子查询中的分析'AAAA'
来保持count()
值的运行计数以及总计数。然后我们调整外部查询的select
子句中的组编号(可以从运行计数中轻松计算),并使用运行计数(对于null
列中的a
)和'AAAA'
子句中的总计数(a
列中的where
),以确定要在输出中保留哪些行。
该代码非常密切地遵循此逻辑解决方案描述。
select a, b, ceil(c/2) as grp
from (
select a, b, count(a) over (order by b) as c, count(a) over () as max_c
from t
)
where a is null and c < max_c and mod(c, 2) = 1
or a is not null and c <= 2 * trunc(max_c/2)
;
A B GRP
---- ---------------- ---
AAAA 2017/01/01 02:00 1
2017/01/01 02:30 1
AAAA 2017/01/01 03:00 1
AAAA 2017/01/01 04:30 2
2017/01/01 05:00 2
AAAA 2017/01/01 05:30 2
为了好玩,为了说明升级到Oracle 12的好处,以下是使用match_recognize
子句(在12.1中添加)非常容易实现的方法:
select a, b, grp
from t
match_recognize(
order by b
measures match_number() as grp
all rows per match
pattern ( h x*? h )
define h as h.a = 'AAAA'
);