Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Transpose Hasil Query di Oracle 11g

Anda sudah dekat - yang Anda inginkan adalah kombinasi UNPIVOT dan 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

Kueri ini

  • mengonversi kolom membaca1, membaca2, membaca3 menjadi baris yang terpisah (namanya masuk ke reading_name , nilai menjadi reading_value ); ini memberi kita satu baris per (elemen,reading_name)
  • mengonversi baris 1, 2*, 3 (nilai untuk elemen ) ke dalam kolom '1', '2', '3'; ini memberi kita satu baris per reading_name

PERBARUI

Jika daftar elemen tidak diketahui sampai waktu berjalan (misalnya karena pengguna memiliki opsi untuk memilihnya), Anda memerlukan pendekatan yang lebih dinamis. Berikut adalah salah satu solusi yang secara dinamis membuat pernyataan SQL untuk daftar elemen yang diberikan dan menggunakan sys_refcursor untuk kumpulan hasil.

-- 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;

Cara Anda menggunakan kursor yang dikembalikan dari fungsi ini bergantung pada lingkungan yang Anda gunakan - dalam SQL/Plus Anda dapat mencetaknya, dan sebagian besar binding Oracle bahasa pemrograman mendukungnya secara langsung.

PERINGATAN: Meskipun kode ini berfungsi untuk data yang diberikan, kode ini bahkan tidak memiliki pemeriksaan kesalahan dasar. Ini sangat penting karena SQL dinamis selalu menjadi target serangan injeksi SQL.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PLS-00201 pengenal 'PACKAGENAME.PROCEDURENAME' harus dideklarasikan

  2. Penanganan data benih di patching online R12.2

  3. Penyetelan Sempurna Oracle DG40DBC

  4. Mengonversi perbedaan waktu ke format tertentu di Oracle

  5. Tidak ada kredensial yang tersedia dalam paket keamanan saat koneksi ke Oracle dilakukan