SQL Group By:当列具有特殊值时拆分组

时间:2018-02-26 15:04:33

标签: oracle

我有一个包含以下列的表:

SerialNr  Date        Processstep  Comment  
--------  ----------  -----------  ----------
    2300  01.01.2018  Step 01      Comment01  
    2300  02.01.2018  Step 02      Comment02  
    2300  03.01.2018  Step 03      Comment03  
    2300  04.01.2018  Finished     Comment04  
    2300  05.01.2018  Step 04      Comment05  
    2300  06.01.2018  Step 05      Comment06  
    2300  07.01.2018  Finished     Comment07  
    2302  01.01.2018  Step 01      Comment08  
    2302  02.01.2018  Step 02      Comment09  
    2302  03.01.2018  Step 03      Comment10  
    2302  04.01.2018  Finished     Comment11  
    2302  05.01.2018  Step 04      Comment12  
    2302  06.01.2018  Step 05      Comment13  
    2302  07.01.2018  Finished     Comment14  

我现在想要一张包含以下信息的表格:

SerialNr  Processstep                          Comment  
--------  -----------------------------------  -------------------------------------------
    2300  Step 01, Step 02, Step 03, Finished  Comment01, Comment02, Comment03, Comment 04  
    2300  Step 04, Step 05, Finished           Comment05, Comment06, Comment07  
    2302  Step 01, Step 02, Step 03, Finished  Comment08, Comment09, Comment10, Comment 11  
    2302  Step 04, Step 05, Finished           Comment12, Comment13, Comment14

所以我想对SerialNr进行分组,但是也希望将此组拆分到Processstep Finished发生的位置。

任何简单的方法吗?到现在为止,我只能按SerienNr进行分组。我不知道如何在Processstep Finished分割小组:

SELECT 
SerienNr, 
listagg(Processstep, ' - ') within group (order by Date),
listagg(Comment, ' - ') within group (order by Date)
FROM table
GROUP BY SerienNr

2 个答案:

答案 0 :(得分:2)

我更改了一些标识符:您的数据库中肯定没有名为table的表。您不能拥有名为comment的列(它是保留字),您不应该有列date。将来,请显示实际名称 - 没有人可以提供这样的非法名称进行测试。

此外 - 您的LISTAGG使用-,但您使用,显示输出 - 我不知道您是如何做到的。

反正:

select   serialnr, listagg(processstep, ', ') within group (order by dt) as processstep,
                   listagg(comm, ', ')        within group (order by dt) as comm
from     (
           select serialnr, dt, processstep, comm,
                  count(case processstep when 'Finished' then 1 end)
                        over (partition by serialnr order by dt desc) as grp
           from   tbl
         )
group by serialnr, grp
order by serialnr, min(dt)  --  If needed
;

答案 1 :(得分:1)

你需要有另一个栏目,你可以根据你的“完成”行进行分组。

select SerialNr, Date, Processstep, Comment, sum(grp) over (partition by SerialNr order by date) as grp_id from (
select *, 
lag(case Processstep  when 'Finished' then 1 else 0 end) 
over (partition by SerialNr order by date) as grp
from table
)

SerialNr    Date        Processstep  Comment      grp_id
2300        01.01.2018  Step 01      Comment01    0
2300        02.01.2018  Step 02      Comment02    0
2300        03.01.2018  Step 03      Comment03    0
2300        04.01.2018  Finished     Comment04    0
2300        05.01.2018  Step 04      Comment05    1
2300        06.01.2018  Step 05      Comment06    1
2300        07.01.2018  Finished     Comment07    1
2302        01.01.2018  Step 01      Comment08    0
2302        02.01.2018  Step 02      Comment09    0
2302        03.01.2018  Step 03      Comment10    0
2302        04.01.2018  Finished     Comment11    0
2302        05.01.2018  Step 04      Comment12    1
2302        06.01.2018  Step 05      Comment13    1
2302        07.01.2018  Finished     Comment14    1

从此表中,您可以再次应用相同的查询,但您按SerienNr分组,grp_id