Oracle 将行转换为列
Oracle pivot rows to columns
我有以下表格:
TABLE1
------
id name
1 n1
2 n2
TABLE2
------
id tipo valor
1 t1 v1
1 t2 v2
2 t1 v1
2 t2 v5
2 t3 v3
我正在尝试获取:
id name t1 t2 t3
1 n1 v1 v2 -
2 n2 v1 v5 v3
可能吗?我一直在寻找示例,但仍然没有弄清楚。
谢谢!
您可以使用条件聚合:
select t1.id, t1.name,
max(case when t2.typo = 't1' then t2.valor end) as t1,
max(case when t2.typo = 't2' then t2.valor end) as t2,
max(case when t2.typo = 't3' then t2.valor end) as t3
from table1 t1
inner join table2 t2 on t2.id = t1.id
group by t1.id, t1.name
typo
的 returns null
值不存在。如果你想要 '-'
,你可以用 coalesce()
包围条件聚合,像这样:
coalesce(max(case when t2.typo = 't1' then t2.valor end), '-') as t1
一个选项是使用 PIVOT
子句
SELECT *
FROM (SELECT t1.*, t2.tipo, t2.valor
FROM table1 t1
JOIN table2 t2
ON t2.id = t1.id)
PIVOT
(
MAX(valor) FOR tipo IN ( 't1' AS "t1", 't2' AS "t2", 't3' AS "t3" )
)
但这是静态的,例如。需要更新,因为添加了 tipo
列的不同值。为了让它动态化,你可以创建一个函数
CREATE OR REPLACE FUNCTION Get_Pivoted_Cols RETURN SYS_REFCURSOR IS
v_recordset SYS_REFCURSOR;
v_sql VARCHAR2(32767);
v_cols VARCHAR2(32767);
BEGIN
SELECT LISTAGG( ''''||tipo||''' AS "'||tipo||'"' , ',' )
WITHIN GROUP ( ORDER BY tipo )
INTO v_cols
FROM ( SELECT DISTINCT tipo FROM table2 );
v_sql := 'SELECT *
FROM (SELECT t1.*, t2.tipo, t2.valor
FROM table1 t1
JOIN table2 t2
ON t2.id = t1.id)
PIVOT
(
MAX(valor) FOR tipo IN ( '|| v_cols ||' )
)';
OPEN v_recordset FOR v_sql;
RETURN v_recordset;
END;
/
然后使用
调用
VAR rc REFCURSOR
EXEC :rc := Get_Pivoted_Cols;
PRINT rc
来自 SQL 开发者控制台。
我有以下表格:
TABLE1
------
id name
1 n1
2 n2
TABLE2
------
id tipo valor
1 t1 v1
1 t2 v2
2 t1 v1
2 t2 v5
2 t3 v3
我正在尝试获取:
id name t1 t2 t3
1 n1 v1 v2 -
2 n2 v1 v5 v3
可能吗?我一直在寻找示例,但仍然没有弄清楚。
谢谢!
您可以使用条件聚合:
select t1.id, t1.name,
max(case when t2.typo = 't1' then t2.valor end) as t1,
max(case when t2.typo = 't2' then t2.valor end) as t2,
max(case when t2.typo = 't3' then t2.valor end) as t3
from table1 t1
inner join table2 t2 on t2.id = t1.id
group by t1.id, t1.name
typo
的 returns null
值不存在。如果你想要 '-'
,你可以用 coalesce()
包围条件聚合,像这样:
coalesce(max(case when t2.typo = 't1' then t2.valor end), '-') as t1
一个选项是使用 PIVOT
子句
SELECT *
FROM (SELECT t1.*, t2.tipo, t2.valor
FROM table1 t1
JOIN table2 t2
ON t2.id = t1.id)
PIVOT
(
MAX(valor) FOR tipo IN ( 't1' AS "t1", 't2' AS "t2", 't3' AS "t3" )
)
但这是静态的,例如。需要更新,因为添加了 tipo
列的不同值。为了让它动态化,你可以创建一个函数
CREATE OR REPLACE FUNCTION Get_Pivoted_Cols RETURN SYS_REFCURSOR IS
v_recordset SYS_REFCURSOR;
v_sql VARCHAR2(32767);
v_cols VARCHAR2(32767);
BEGIN
SELECT LISTAGG( ''''||tipo||''' AS "'||tipo||'"' , ',' )
WITHIN GROUP ( ORDER BY tipo )
INTO v_cols
FROM ( SELECT DISTINCT tipo FROM table2 );
v_sql := 'SELECT *
FROM (SELECT t1.*, t2.tipo, t2.valor
FROM table1 t1
JOIN table2 t2
ON t2.id = t1.id)
PIVOT
(
MAX(valor) FOR tipo IN ( '|| v_cols ||' )
)';
OPEN v_recordset FOR v_sql;
RETURN v_recordset;
END;
/
然后使用
调用VAR rc REFCURSOR
EXEC :rc := Get_Pivoted_Cols;
PRINT rc
来自 SQL 开发者控制台。