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 đề đó.