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

PostgreSQL 9.3:Bảng tổng hợp động

Bạn có thể thực hiện việc này với crosstab() từ bảng mô-đun bổ sung:

SELECT b
     , COALESCE(a1, 0) AS "A1"
     , COALESCE(a2, 0) AS "A2"
     , COALESCE(a3, 0) AS "A3"
     , ... -- all the way up to "A30"
FROM   crosstab(
         'SELECT colb, cola, 1 AS val FROM matrix
          ORDER  BY 1,2'
        , $$SELECT 'A'::text || g FROM generate_series(1,30) g$$
       ) AS t (b text
             , a1  int, a2  int, a3  int, a4  int, a5  int, a6  int
             , a7  int, a8  int, a9  int, a10 int, a11 int, a12 int
             , a13 int, a14 int, a15 int, a16 int, a17 int, a18 int
             , a19 int, a20 int, a21 int, a22 int, a23 int, a24 int
             , a25 int, a26 int, a27 int, a28 int, a29 int, a30 int);

Nếu NULL thay vì 0 cũng hoạt động, nó có thể chỉ là SELECT * trong truy vấn bên ngoài.
Giải thích chi tiết:

  • Truy vấn bảng chéo PostgreSQL

Cái "khó" đặc biệt ở đây:không có "giá trị" thực tế. Vì vậy, hãy thêm 1 AS val là cột cuối cùng.

Số lượng danh mục không xác định

Không thể thực hiện được một truy vấn động hoàn toàn (với loại kết quả không xác định) trong một truy vấn. Bạn cần hai truy vấn. Đầu tiên hãy xây dựng động một câu lệnh như trên, sau đó thực thi nó. Chi tiết:

  • Chọn nhiều giá trị max () bằng một câu lệnh SQL duy nhất

  • PostgreSQL chuyển đổi cột thành hàng? Chuyển vị?

  • Tự động tạo cột cho bảng chéo trong PostgreSQL

  • Thay thế động cho trục xoay với CASE và GROUP BY

Quá nhiều danh mục

Nếu bạn vượt quá số cột tối đa (1600), thì bảng chéo cổ điển là không thể, vì kết quả không thể được biểu thị bằng các cột riêng lẻ. (Ngoài ra, mắt người khó có thể đọc được một bảng có nhiều cột như vậy)

Mảng hoặc các loại tài liệu như hstore hoặc jsonb là sự thay thế. Đây là một giải pháp với mảng:

SELECT colb, array_agg(cola) AS colas
FROM  (
   SELECT colb, right(colb, -1)::int AS sortb
        , CASE WHEN m.cola IS NULL THEN 0 ELSE 1 END AS cola
   FROM        (SELECT DISTINCT colb FROM matrix) b
   CROSS  JOIN (SELECT DISTINCT cola FROM matrix) a
   LEFT   JOIN matrix m USING (colb, cola)
   ORDER  BY sortb, right(cola, -1)::int 
   ) sub
GROUP  BY 1, sortb
ORDER  BY sortb;
  • Xây dựng lưới giá trị hoàn chỉnh với:

                (SELECT DISTINCT colb FROM matrix) b
    CROSS  JOIN (SELECT DISTINCT cola FROM matrix) a
    
  • LEFT JOIN các kết hợp hiện có, sắp xếp theo phần số của tên và tổng hợp thành mảng.

    • right(colb, -1)::int cắt ký tự đứng đầu từ 'A3' và chuyển các chữ số thành số nguyên để chúng ta có thứ tự sắp xếp thích hợp.

Ma trận cơ bản

Nếu bạn chỉ muốn một bảng gồm 0 một 1 ở đâu x = y , cái này có thể rẻ hơn:

SELECT x, array_agg((x = y)::int) AS y_arr
FROM   generate_series(1,10) x
     , generate_series(1,10) y
GROUP  BY 1
ORDER  BY 1;

SQL Fiddle xây dựng dựa trên cái bạn đã cung cấp trong các bình luận.

Lưu ý rằng sqlfiddle.com hiện có một lỗi giết chết hiển thị giá trị mảng. Vì vậy, tôi truyền sang text ở đó để giải quyết vấn đề đó.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Hướng dẫn về Pgpool cho PostgreSQL:Phần một

  2. Đặt lược đồ trong PostgreSQL JDBC dường như không hoạt động

  3. Định cấu hình PostgreSQL cho sự liên tục trong kinh doanh

  4. Gặp lỗi:Xác thực ngang hàng không thành công đối với postgres của người dùng, khi cố gắng làm cho pgsql hoạt động với đường ray

  5. Cách ánh xạ PostgreSQL enum với JPA và Hibernate