oracle在条件上选择mulitple记录为1

时间:2017-02-20 10:47:52

标签: sql oracle

表:CODES_TABLE

Serial   - Code -  DateTime
A123        B2          01/01/17:14:00
A124        B2          01/01/17:14:00
A123        B3          01/01/17:14:05
A123        B4          01/01/17:14:08
A124        B3          01/01/17:14:00
A128        B2          03/01/17:14:00
A129        B2          03/01/17:14:00
A129        B4          02/01/17:14:00

我想要获得的是所有已经生成代码B2,B3和B4的序列的列表并且已经按照给定的顺序生成它 - 即首先是B2,然后是B3然后是B4所以在这个例子中 - 只有序列A123 < / p>

1 个答案:

答案 0 :(得分:1)

假设根据您的输入数据,codeserial只发生一次,这可能是一种方式:

/* test case */
with testTable(Serial,Code, DateTime) as (
    select 'A123',   'B2', to_date('01/01/17:14:00', 'dd/mm/yy:hh24:mi') from dual union all
    select 'A124',   'B2', to_date('01/01/17:14:00', 'dd/mm/yy:hh24:mi') from dual union all
    select 'A123',   'B3', to_date('01/01/17:14:05', 'dd/mm/yy:hh24:mi') from dual union all
    select 'A123',   'B4', to_date('01/01/17:14:08', 'dd/mm/yy:hh24:mi') from dual union all
    select 'A124',   'B3', to_date('01/01/17:14:00', 'dd/mm/yy:hh24:mi') from dual union all
    select 'A128',   'B2', to_date('03/01/17:14:00', 'dd/mm/yy:hh24:mi') from dual union all
    select 'A129',   'B2', to_date('03/01/17:14:00', 'dd/mm/yy:hh24:mi') from dual union all
    select 'A129',   'B4', to_date('02/01/17:14:00', 'dd/mm/yy:hh24:mi') from dual
)
/* the query */
select serial
from testTable
group by serial
having listagg( case when code in ('B2', 'B3', 'B4') then code end) within group ( order by dateTime) like '%B2B3B4%'

此处的想法是按serial汇总,为每个serial构建一个包含codes的字符串,按dateTime排序。

假设每个code只能为serial出现一次,那么符合您条件的唯一serials将包含包含'B2B3B4'的字符串。

CASE用于处理您需要检查序列是否B2, B3, B5甚至可能发生B4的情况。

这应该更好地解释这应该如何运作:

select serial, listagg( case when code in ('B2', 'B3', 'B4') then code end) within group ( order by dateTime) as string
from testTable
group by serial;

SERI STRING
---- ---------------
A123 B2B3B4
A124 B2B3
A128 B2
A129 B4B2