Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Chuyển đổi kết quả truy vấn trong Oracle 11g

Bạn đã gần xong - thứ bạn muốn là sự kết hợp của UNPIVOTPIVOT :

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

Truy vấn này

  • chuyển đổi các cột đọc1, đọc2, đọc3 thành các hàng riêng biệt (tên chuyển thành read_name , giá trị thành read_value ); điều này cung cấp cho chúng tôi một hàng cho mỗi (phần tử, read_name)
  • chuyển đổi hàng 1, 2 *, 3 (các giá trị cho phần tử ) thành các cột '1', '2', '3'; điều này cung cấp cho chúng tôi một hàng cho mỗi read_name

CẬP NHẬT

Nếu danh sách các phần tử không được biết cho đến thời gian chạy (ví dụ:vì người dùng có tùy chọn chọn chúng), bạn cần một cách tiếp cận năng động hơn. Đây là một giải pháp tạo động một câu lệnh SQL cho danh sách các phần tử đã cho và sử dụng sys_refcursor cho tập hợp kết quả.

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

Cách bạn sử dụng con trỏ được trả về từ hàm này tùy thuộc vào môi trường bạn đang sử dụng - trong SQL / Plus, bạn chỉ có thể in nó và các ràng buộc Oracle của hầu hết các ngôn ngữ lập trình đều hỗ trợ nó ngay lập tức.

CAVEAT: Mặc dù mã này hoạt động cho dữ liệu được cung cấp, nhưng nó thậm chí còn thiếu tính năng kiểm tra lỗi cơ bản. Điều này đặc biệt quan trọng vì SQL động luôn là mục tiêu có thể xảy ra cho các cuộc tấn công SQL injection.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Chọn các hàng cho đến khi điều kiện được đáp ứng

  2. Tìm câu hỏi được trả lời chính xác trong bài kiểm tra trực tuyến với câu hỏi đơn và câu hỏi nhiều lựa chọn

  3. Dấu thời gian Oracle, Giá trị tối đa và tối thiểu

  4. Gọi một thủ tục Oracle PL / SQL trong Java bằng cách sử dụng CallableStatement với tham số boolean IN gây ra lỗi tiên tri PLS-00306:

  5. Tại sao kiểu dữ liệu Long đã được thay thế bằng LOB trong Oracle?