用CASE合并行

时间:2018-11-22 11:52:17

标签: sql oracle case

Customer_id   item_type   item_code
1             a           123
1             b           456
1             c           789

我已经使用CASE根据“ item_type”列中包含的内容将“ item_code”划分为不同的列。同一张表中的所有日期。

customer_id   item_type_a   item_type_b   item_type_c
1             123
1                            456
1                                         789

但是,我真正需要做的输出到一行。

customer_id   item_type_a   item_type_b   item_type_c
1             123           456           789

建议表示赞赏。

4 个答案:

答案 0 :(得分:4)

使用聚合:

Dude(name='Pepe')

答案 1 :(得分:1)

您可以使用correlated subquery作为替代选项:

select max(customer_id) as customer_id,
       ( select item_code from tab t where t.customer_id = r.customer_id and 'a' = r.item_type ) 
        as item_type_a,
       ( select item_code from tab t where t.customer_id = r.customer_id and 'b' = r.item_type ) 
        as item_type_b, 
       ( select item_code from tab t where t.customer_id = r.customer_id and 'c' = r.item_type ) 
        as item_type_c
  from tab r 
 group by r.customer_id;

或者,您可以将函数创建为

create or replace function get_item_code( 
                                         i_item_type   tab.item_type%type,
                                         i_customer_id tab.customer_id%type
                                         ) is
 o_item_code tab.item_code%type  
begin
 select item_code
   into o_item_code 
   from tab t 
  where t.customer_id = i_customer_id 
    and t.item_type = i_item_type;

  return o_item_code;

 exception when no_data_found then return null;
end;

然后发布

select max(customer_id) as customer_id,
       get_item_code('a',customer_id) as item_type_a,
       get_item_code('b',customer_id) as item_type_b,
       get_item_code('c',customer_id) as item_type_c
  from tab 
 group by customer_id;

答案 2 :(得分:1)

除了其他给出的有效和正确答案外,您还可以使用PIVOT子句,实际上是针对此类情况(您要从基于行的数据组织转换为基于列的数据组织)创建的)。 看起来像这样:

select *
from tab
pivot (
  max(item_code)
  for (item_type)
  in ('a' as item_type_a, 'b' as item_type_b, 'c' as item_type_c)
)
order by customer_id

对于此示例数据:

CUSTOMER_ID | ITEM_TYPE | ITEM_CODE
------------+-----------+----------
          1 | a         | 123
          1 | b         | 456
          1 | c         | 789
          2 | a         | ABC
          2 | b         | DEF
          2 | c         | GHI
          3 | a         | XYZ
          3 | b         | PQR
          4 | a         | MMM
          4 | a         | NNN

它给出那些结果:

CUSTOMER_ID | ITEM_TYPE_A | ITEM_TYPE_B | ITEM_TYPE_C
------------+-------------+-------------+------------
          1 | 123         | 456         | 789
          2 | ABC         | DEF         | GHI
          3 | XYZ         | PQR         |
          4 | NNN         |             |

查看此SQL Fiddle的工作原理(并与基于GROUP BY的等效查询进行比较)。 如您所见,它与GROUP BY查询基本具有相同的执行计划,因此,其用途更多是为了清楚,而不是性能。还值得一提的是,PIVOT在Oracle 11g之前不可用,因此,如果您还针对较早的版本,则选择GROUP BY

当存在多行具有customer_iditem_type相同组合的行时,您尚未指定如何处理个案(请参见示例数据中customer_id等于4的个案) 。我对GROUP BY使用的方法与其他方法相同,所以我选择了MAX

答案 3 :(得分:0)

如果您必须保留桌子,可以使用:

select customer_id,
       max(item_type_a) as item_type_a,
       max(item_type_b) as item_type_b,
       max(item_type_c) as item_type_c
from tableName
group by customer_id;

编辑:

我假设他对表(customer_id item_type_a item_type_b item_type_c)的解决方案是此查询的基础