有没有办法用SQL查询将第一个表映射到第二个表,或者如果太复杂,是否有PL / SQL块?
原始
--------------------------------------
| col1 | col2 | col3 | col4 |
--------------------------------------
| key | case 1 | case 2 | case 3 |
| value1 | v1c1 | v1c2 | v1c3 |
| value2 | v2c1 | v2c2 | v2c3 |
--------------------------------------
目标
-----------------------------
| key | case | result |
-----------------------------
| value1 | case 1 | v1c1 |
| value1 | case 2 | v1c2 |
| value1 | case 3 | v1c3 |
| value2 | case 1 | v2c1 |
| value2 | case 2 | v2c2 |
| value2 | case 3 | v2c3 |
-----------------------------
原始表可以具有可变数量的列,“key”是硬编码字符串,并且始终位于原始表的第1列中。没有其他行在第1列中具有“键”,因此该行是唯一的轴。
谢谢
答案 0 :(得分:1)
原始表可以有一个变量 列数
真的?
直接的方法是选择和合并你想要的部分。
select col1 as key, 'case1' as case, col2 as result
from test
where col1 <> 'key'
union all
select col1 as key, 'case2' as case, col3 as result
from test
where col1 <> 'key'
union all
select col1 as key, 'case3' as case, col4 as result
from test
where col1 <> 'key'
直截了当,但不是动态的。
稍后。 。 强>
根据您的评论。 。 。虽然我认为没必要。
select col1 as key, (select col2 from test where col1='key') as case, col2 as result
from test
where col1 <> 'key'
union all
select col1 as key, (select col3 from test where col1='key') as case, col3 as result
from test
where col1 <> 'key'
union all
select col1 as key, (select col4 from test where col1='key') as case, col4 as result
from test
where col1 <> 'key'
Oracle 11还支持UNPIVOT
,我还没有使用过。
答案 1 :(得分:1)
我不知道哪些部分可以改变,但这应该是一个开始。如果列名称可以更改(键,案例1等),则必须使用另一个查询来获取正确的列名称。如果您有任何问题,请随时询问:
declare
v_query VARCHAR2(5000);
v_case VARCHAR2(255);
v_colcount PLS_INTEGER;
begin
-- Get number of columns
select count(*)
INTO v_colcount
from user_tab_columns
where table_name = 'T1';
-- Build case statement to get correct value for result column
v_case := 'case';
for i in 1 .. v_colcount-1
loop
v_case := v_case||' when rn = '||to_char(i)||' then col'||to_char(i+1);
end loop;
v_case := v_case||' end result';
-- Build final query
v_query := 'select col1 key, ''case ''||rn case, '||v_case||'
from t1
cross join (
select rownum rn
from dual
connect by level <= '||to_char(v_colcount-1)||'
) cj
where col1 <> ''key''
order by key, case';
-- Display query (would probably be replaced with an insert using execute immediate)
dbms_output.put_line(v_query);
end;
这会产生以下查询(假设您的原始表名为t1):
select col1 key, 'case '||rn case, case when rn = 1 then col2 when rn = 2 then col3 when rn = 3 then col4 end result
from t1
cross join (
select rownum rn
from dual
connect by level <= 3
) cj
where col1 <> 'key'
order by key, case
答案 2 :(得分:1)
试试这个:
with data as
(select level l from dual connect by level <= 3)
select col1,
'case' || l as "case",
decode(l,1,col2,2,col3,3,col4) as "values"
from myTable, data
order by 1,2;
干杯
答案 3 :(得分:1)
如果允许动态sql,则可以使用一个查询填写所有要求:
SELECT col1 as "key"
,extractvalue(dbms_xmlgen.getXMLType('select "' || tc.Column_Name ||
'" as v from Original where col1 = ''key''')
,'/ROWSET/ROW/V') "case"
,extractvalue(dbms_xmlgen.getXMLType('select "' || tc.Column_Name ||
'" as v from Original where col1 = ''' ||
replace(col1, '''', '''''') || '''')
,'/ROWSET/ROW/V') "result"
FROM Original
,(SELECT Column_Name
FROM All_Tab_Columns tc
WHERE tc.Owner = 'YOURSCHEMA'
and tc.Table_Name = 'ORIGINAL'
and Column_Name != 'COL1'
ORDER BY tc.COLUMN_ID) tc
WHERE col1 != 'key'
ORDER BY "key"
,"case"
根据要求提供更多详情: