如何将一个客户的一个表中的两个不同值组合成一行

时间:2017-05-18 18:09:42

标签: sql oracle

我想列出已订购不同代码的ID。我不想列出只订购一个代码的ID(即ID 4,5)。

ID      product      code
1       Apple        145
1       Grapes       146
2       Orange       147
2       Apple        145
2       Plum         148 
3       Grapes       146
3       Orange       147
4       Grapes       146
5       Orange       147

我希望它看起来像这样

ID      Codes       
1     145 | 146
2     147 | 145 | 148
3     146 | 147      

感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

您需要GROUP BY id,并且“多个订单”的条件会进入HAVING子句(因为它是每个组的约束,而不是输入数据中的每一行) )。聚合是使用LISTAGG完成的。

with
     test_data ( id, product, code ) as (
       select 1, 'Apple' , 145 from dual union all
       select 1, 'Grapes', 146 from dual union all
       select 2, 'Orange', 147 from dual union all
       select 2, 'Apple' , 145 from dual union all
       select 2, 'Plum'  , 148 from dual union all
       select 3, 'Grapes', 146 from dual union all
       select 3, 'Orange', 147 from dual union all
       select 4, 'Grapes', 146 from dual union all
       select 5, 'Orange', 147 from dual
     )
--  End of test data (not part of the solution). Query begins below this line.
select   id, listagg(code, ' | ') within group (order by id) as codes
from     test_data
group by id
having   count(*) > 1
;

ID  CODE
--  ---------------
 1  145 | 146
 2  145 | 147 | 148
 3  146 | 147

但是,在Oracle 10中,您没有LISTAGG()。在Oracle 11.2之前,获得相同结果的常用方法是使用分层查询,如下所示:

select id, ltrim(sys_connect_by_path(code, ' | '), ' | ') as codes
from   (
         select id, code,
                row_number() over (partition by id order by code) as rn
         from   test_data
       )
where connect_by_isleaf = 1 and level > 1
connect by rn = prior rn + 1
       and prior id = id
       and prior sys_guid() is not null
start with rn = 1
;

<强> EDITED

如果首先需要“区分”相同ID的重复CODE,那么 - 使用第二个解决方案 - 需要在最里面的子查询中进行以下更改:

  • SELECT ID, CODE, ...更改为SELECT DISTINCT ID, CODE, ...

  • ROW_NUMBER()更改为DENSE_RANK()