आप करीब हैं - आप जो चाहते हैं वह UNPIVOT
. का संयोजन है और PIVOT
:
with T AS (
select 1 as element, 1.1 as reading1, 1.2 as reading2, 1.3 as reading3 from dual union all
select 2 as element, 2.1 as reading1, 2.2 as reading2, 2.3 as reading3 from dual union all
select 3 as element, 3.1 as reading1, 3.2 as reading2, 3.3 as reading3 from dual
)
select * from (
select * from t
unpivot (reading_value
for reading_name in ("READING1", "READING2", "READING3")
)
pivot(max(reading_value) for element in (1,2,3)
)
)
order by reading_name
यह प्रश्न
- स्तंभों को रूपांतरित करता है रीडिंग1, रीडिंग2, रीडिंग3 अलग पंक्तियों . में (नाम reading_name . में चला जाता है , मान reading_value . में ); यह हमें प्रति पंक्ति एक पंक्ति देता है (तत्व, रीडिंग_नाम)
- पंक्तियों को रूपांतरित करता है 1, 2*, 3 (तत्व . के लिए मान ) कॉलम '1', '2', '3' में; यह हमें प्रति रीडिंग_नाम एक पंक्ति देता है
अपडेट करें
यदि तत्वों की सूची रन टाइम तक नहीं पता है (उदाहरण के लिए क्योंकि उपयोगकर्ता के पास उन्हें चुनने का विकल्प है), तो आपको अधिक गतिशील दृष्टिकोण की आवश्यकता है। यहां एक समाधान है जो तत्वों की दी गई सूची के लिए गतिशील रूप से SQL कथन बनाता है और sys_refcursor
का उपयोग करता है परिणाम सेट के लिए।
-- setup table
create table T AS
select 1 as element, 1.1 as reading1, 1.2 as reading2, 1.3 as reading3 from dual union all
select 2 as element, 2.1 as reading1, 2.2 as reading2, 2.3 as reading3 from dual union all
select 3 as element, 3.1 as reading1, 3.2 as reading2, 3.3 as reading3 from dual ;
/
declare
l_Elements dbms_sql.Number_Table;
function pivot_it(p_Elements in dbms_sql.Number_Table)
return sys_refcursor is
l_SQL CLOB := empty_clob();
l_Result sys_refcursor;
begin
l_SQL := '
select * from (
select * from t
unpivot (reading_value
for reading_name in ("READING1", "READING2", "READING3")
)
pivot(max(reading_value) for element in (';
for i in 1 .. p_Elements.count
loop
l_SQL := l_SQL || to_char(p_Elements(i)) || ',';
end loop;
-- remove trailing ','
l_SQL := regexp_replace(l_SQL, ',$');
l_SQL := l_SQL || ')
)
)';
dbms_output.put_line(l_SQL);
open l_Result for l_SQL;
return l_Result;
end;
begin
l_Elements(1) := 1;
l_Elements(2) := 2;
-- uncomment this line to get all 3 elements
-- l_Elements(3) := 3;
-- return the cursor into a bind variable (to be used in the host environment)
:p_Cursor := pivot_it(l_Elements);
end;
आप इस फ़ंक्शन से लौटाए गए कर्सर का उपयोग कैसे करते हैं, यह आपके द्वारा उपयोग किए जा रहे वातावरण पर निर्भर करता है - SQL/Plus में आप इसे केवल प्रिंट कर सकते हैं, और अधिकांश प्रोग्रामिंग भाषाओं की Oracle बाइंडिंग इसे आउट-ऑफ-द-बॉक्स का समर्थन करती है।
चेतावनी: जबकि यह कोड प्रदान किए गए डेटा के लिए काम करता है, इसमें बुनियादी त्रुटि जाँच का भी अभाव है। यह विशेष रूप से महत्वपूर्ण है क्योंकि गतिशील एसक्यूएल हमेशा एसक्यूएल इंजेक्शन हमलों के लिए एक संभावित लक्ष्य है।