我很难使多条记录成为oracle中具有多列的一条记录。这是我的查询:
SELECT cnim, ckddos FROM tjadsidangast j, tsidangast s
WHERE j.cnojadwal=s.cnojadwal AND cnim='1111500003'
结果:
+------------+--------+
| CNIM | CKDDOS |
+------------+--------+
| 1111500003 | 00105 |
| 1111500003 | 00060 |
| 1111500003 | 00126 |
+------------+--------+
我尝试过以下查询:
SELECT cnim,
LTRIM(MAX(SYS_CONNECT_BY_PATH(ckddos,','))
KEEP (DENSE_RANK LAST ORDER BY curr),',') AS elements
FROM (SELECT cnim,
ckddos,
ROW_NUMBER() OVER (PARTITION BY cnim ORDER BY cstatus) AS curr,
ROW_NUMBER() OVER (PARTITION BY cnim ORDER BY cstatus) -1 AS prev
FROM tsidangast j, tjadsidangast s WHERE j.cnojadwal=s.cnojadwal AND
cnim='1111500003')
GROUP BY cnim
CONNECT BY prev = PRIOR curr AND cnim = PRIOR cnim
START WITH curr = 1;
结果是:
+------------+---------------------+
| CNIM | ELEMENTS |
+------------+---------------------+
| 1111500003 | 00126,00105,00060 |
+------------+---------------------+
我的问题是:如何使结果成为此输出:
+------------+--------+-------+-------+
| CNIM | MD | P1 | P2 |
+------------+--------+-------+-------+
| 1111500003 | 00126 | 00105 | 00060 |
+------------+--------+-------+-------+
谢谢
答案 0 :(得分:0)
使用pivot
代替缓慢的(这里不需要)分层查询:
select *
from (select row_number() over (order by cstatus) rn, cnim, ckddos
from your_join
where cnim = '1111500003')
pivot (max(ckddos) for rn in (1 md, 2 p1, 3 p2))
如果这是Oracle 10或更低版本,请将pivot
替换为max(case ...)
:
select cnim,
max(case when rn = 1 then ckddos end) md,
max(case when rn = 2 then ckddos end) p1,
max(case when rn = 3 then ckddos end) p2
from (
select row_number() over (order by cstatus) rn, cnim, ckddos
from your_join
where cnim = '1111500003')
group by cnim
此解决方案类似于@ D-Shih的解决方案,但您不应在查询中对ckddos
值进行硬编码,因为这是您要寻找的。
您应该并且可以硬编码的是行号(1、2、3)。