我有两张桌子:
操作
opCode opDescription
001 DESC_01
002 DESC_02
003 DESC_03
004 DESC_04
.. ..
客户端
opCode cliCode clDescription
001 C001 DESCR xx
001 C002 DESCR yy
002 C005 DESCR bb
002 C001 DESCR cc
002 C006 DESCR gg
002 C003 DESCR dd
.. .. ..
我需要加入并转换列中的行
opCode opDescription cliCode1 clDescription1 cliCode2 clDescription2 cliCode3 clDescription3 .. .. cliCode5 clDescription5
001 DESC_01 C001 DESCRxx C002 DESCRyy
002 DESC_02 C005 DESCRbb C001 DESCRcc C006 DESCRgg C003 DESCRdd
只能存在0到5个链接的客户
任何想法?
答案 0 :(得分:2)
您可以使用row_number()
和条件聚合:
select o.opcode, o.opDescription,
max(case when seqnum = 1 then c.cliCode end) as cliCode1,
max(case when seqnum = 1 then c.clDescription end) as clDescription1,
max(case when seqnum = 2 then c.cliCode end) as cliCode2,
max(case when seqnum = 2 then c.clDescription end) as clDescription2,
max(case when seqnum = 3 then c.cliCode end) as cliCode3,
max(case when seqnum = 3 then c.clDescription end) as clDescription3,
max(case when seqnum = 4 then c.cliCode end) as cliCode4,
max(case when seqnum = 4 then c.clDescription end) as clDescription4,
max(case when seqnum = 5 then c.cliCode end) as cliCode5,
max(case when seqnum = 5 then c.clDescription end) as clDescription5
from operations o left join
(select c.*,
row_number() over (partition by opcode order by cliCode) as seqnum
from clients c
) c
on o.opcode = c.opcode
group by o.opcode, o.opDescription
答案 1 :(得分:0)
这是关于旋转的,一次只有两列:
WITH
-- input data, don't use in real query
operations(opcode,opdescription) AS (
SELECT '001','DESC_01'
UNION ALL SELECT '002','DESC_02'
UNION ALL SELECT '003','DESC_03'
UNION ALL SELECT '004','DESC_04'
)
,
clients(opcode,clicode,cldescription) AS (
SELECT '001','C001','DESCR xx'
UNION ALL SELECT '001','C002','DESCR yy'
UNION ALL SELECT '002','C005','DESCR bb'
UNION ALL SELECT '002','C001','DESCR cc'
UNION ALL SELECT '002','C006','DESCR gg'
UNION ALL SELECT '002','C003','DESCR dd'
)
-- end of input data, start real query just after here, using WITH, not comma
,
join_with_sequence AS (
SELECT
ROW_NUMBER() OVER(PARTITION BY o.opcode ORDER BY clicode) AS seq
, o.opcode
, o.opdescription
, clicode
, cldescription
FROM operations o
JOIN clients USING(opcode)
)
SELECT
opcode
, opdescription
, MAX(CASE seq WHEN 1 THEN clicode END) AS clicode1
, MAX(CASE seq WHEN 1 THEN cldescription END) AS cldescription1
, MAX(CASE seq WHEN 2 THEN clicode END) AS clicode2
, MAX(CASE seq WHEN 2 THEN cldescription END) AS cldescription2
, MAX(CASE seq WHEN 3 THEN clicode END) AS clicode3
, MAX(CASE seq WHEN 3 THEN cldescription END) AS cldescription3
, MAX(CASE seq WHEN 4 THEN clicode END) AS clicode4
, MAX(CASE seq WHEN 4 THEN cldescription END) AS cldescription4
, MAX(CASE seq WHEN 5 THEN clicode END) AS clicode5
, MAX(CASE seq WHEN 5 THEN cldescription END) AS cldescription5
FROM join_with_sequence
GROUP BY
opcode
, opdescription
ORDER BY
opcode
, opdescription
;
opcode|opdescription|clicode1|cldescription1|clicode2|cldescription2|clicode3|cldescription3|clicode4|cldescription4|clicode5|cldescription5
001 |DESC_01 |C001 |DESCR xx |C002 |DESCR yy |- |- |- |- |- |-
002 |DESC_02 |C001 |DESCR cc |C003 |DESCR dd |C005 |DESCR bb |C006 |DESCR gg |- |-
答案 2 :(得分:0)
或者,使用其中一个答案并使用Oracles pivot子句......
WITH
-- input data, don't use in real query
operations(opcode,opdescription) AS (
SELECT '001','DESC_01' from dual
UNION ALL SELECT '002','DESC_02' from dual
UNION ALL SELECT '003','DESC_03' from dual
UNION ALL SELECT '004','DESC_04' from dual
)
,
clients(opcode,clicode,cldescription) AS (
SELECT '001','C001','DESCR xx' from dual
UNION ALL SELECT '001','C002','DESCR yy' from dual
UNION ALL SELECT '002','C005','DESCR bb' from dual
UNION ALL SELECT '002','C001','DESCR cc' from dual
UNION ALL SELECT '002','C006','DESCR gg' from dual
UNION ALL SELECT '002','C003','DESCR dd' from dual
)
-- end of input data, start real query just after here, using WITH, not comma
,
join_with_sequence AS (
SELECT
ROW_NUMBER() OVER(PARTITION BY o.opcode ORDER BY clicode) AS seq
, o.opcode
, o.opdescription
, clicode
, cldescription
FROM operations o
INNER JOIN clients ON (o.opcode = clients.opcode)
)
select * from join_with_sequence
pivot
(
min(cliCode) as cliCode,
min(clDescription) as clDescription
FOR(seq) in (1 as cl1,2 as cl2,3 as cl3,4 as cl4,5 as cl5)
);