如何使用Oracle SQL将多行数据合并为单行?
解决Oracle SQL多行转单行展示的问题
没问题,我来帮你搞定这个把多行数据转成单行展示的需求。咱们先从基础的表结构和测试数据开始,然后一步步实现目标结果。
1. 创建表和插入测试数据
首先是你提供的表结构和测试数据,用Oracle SQL执行即可:
Create table EMP( emp_id number, emp number, code number, date_start date, date_end date ); Insert into EMP (emp_id,emp,code,date_start,date_end) VALUES (1,100,1,sysdate,sysdate + 1/24); Insert into EMP (emp_id,emp,code,date_start,date_end) VALUES (2,100,1,sysdate,sysdate + 1/24); Insert into EMP (emp_id,emp,code,date_start,date_end) VALUES (3,100,2,sysdate,sysdate + 1/24); Insert into EMP (emp_id,emp,code,date_start,date_end) VALUES (4,100,1,sysdate,sysdate + 1/24);
这里sysdate + 1/24代表增加1小时,所以每条code=1的记录时长都是1小时,3条加起来就是3小时;code=2只有1条,时长1小时,正好对应你要的结果。
2. 实现多行转单行的两种方法
方法一:使用条件聚合(灵活通用)
这种方法适合code数量固定或者需要自定义列名的场景,通过CASE WHEN来分组计算每个code的总时长:
SELECT emp, SUM(CASE WHEN code = 1 THEN (date_end - date_start)*24 ELSE 0 END) || ' (hours)' AS CODE_1, SUM(CASE WHEN code = 2 THEN (date_end - date_start)*24 ELSE 0 END) || ' (hours)' AS CODE_2 FROM EMP GROUP BY emp;
解释:
(date_end - date_start)*24:Oracle中日期相减得到的是天数,乘以24转成小时数SUM(CASE ...):只对指定code的记录求和,其他code的记录贡献0|| ' (hours)':把数字和单位拼接起来,符合你要的格式
方法二:使用Oracle PIVOT函数(简洁直观)
Oracle自带的PIVOT函数专门用来行转列,语法更简洁:
SELECT emp, NVL(code_1 || ' (hours)', '0 (hours)') AS CODE_1, NVL(code_2 || ' (hours)', '0 (hours)') AS CODE_2 FROM ( -- 先按emp和code分组计算总时长 SELECT emp, code, SUM((date_end - date_start)*24) AS total_hours FROM EMP GROUP BY emp, code ) PIVOT ( MAX(total_hours) -- 聚合函数,因为分组后每个emp+code只有一行,MAX/SUM都可以 FOR code IN (1 AS code_1, 2 AS code_2) -- 指定要转成列的code值和对应的列名 );
解释:
- 子查询先计算每个emp下每个code的总小时数
PIVOT把code的取值(1、2)转成列,列名分别是code_1、code_2NVL用来处理某个code没有数据的情况,显示0小时
执行结果
两种方法都会得到你期望的结果:
EMP CODE_1 CODE_2 --- ------------- ------------- 100 3 (hours) 1 (hours)
内容的提问来源于stack exchange,提问作者babayaro
相关产品推荐
相关产品推荐

