Một lần nữa, đối với hơn một vài "kiểu dữ liệu", tôi khuyên bạn nên sử dụng crosstab()
:
SELECT * FROM crosstab(
$$SELECT DISTINCT ON (1, 2)
'max' AS "type", data_type, val
FROM tbl
ORDER BY 1, 2, val DESC$$
,$$VALUES ('Final Fantasy'), ('Quake 3'), ('World of Warcraft')$$)
AS x ("type" text, "Final Fantasy" int, "Quake 3" int, "World of Warcraft" int)
Lợi nhuận:
type | Final Fantasy | Quake 3 | World of Warcraft
-----+---------------+---------+-------------------
max | 500 | 1500 | 1200
Giải thích thêm về những điều cơ bản:
PostgreSQL Crosstab Query
Giải pháp động
Điều khó khăn là làm cho điều này hoàn toàn động :để làm cho nó hoạt động cho
- một số không xác định trong số các cột (data_types trong trường hợp này)
- với tên không xác định (lại data_types)
Ít nhất là loại nổi tiếng:integer
trong trường hợp này.
Tóm lại:điều đó là không thể với PostgreSQL hiện tại (bao gồm cả 9.3). Có các phép gần đúng với các kiểu đa hình và các cách để vượt qua các hạn chế với các kiểu mảng hoặc hstore. Có thể đủ tốt cho bạn. Nhưng điều đó hoàn toàn không thể để nhận được kết quả với các cột riêng lẻ trong một truy vấn SQL. SQL rất khắt khe về các loại và muốn biết những gì mong đợi trở lại.
Tuy nhiên , nó có thể được thực hiện với hai truy vấn. Cái đầu tiên xây dựng truy vấn thực tế để sử dụng. Xây dựng dựa trên trường hợp đơn giản trên:
SELECT $f$SELECT * FROM crosstab(
$$SELECT DISTINCT ON (1, 2)
'max' AS "type", data_type, val
FROM tbl
ORDER BY 1, 2, val DESC$$
,$$VALUES ($f$ || string_agg(quote_literal(data_type), '), (') || $f$)$$)
AS x ("type" text, $f$ || string_agg(quote_ident(data_type), ' int, ') || ' int)'
FROM (SELECT DISTINCT data_type FROM tbl) x
Điều này tạo ra truy vấn bạn thực sự cần. Chạy cái thứ hai bên trong cùng một giao dịch để tránh các vấn đề đồng thời.
Lưu ý việc sử dụng chiến lược quote_literal()
và quote_ident()
để khử trùng tất cả các loại tên (đối với cột) bất hợp pháp và ngăn chặn Chèn SQL .
Đừng bối rối bởi nhiều lớp báo giá đô la. Điều đó cần thiết để xây dựng các truy vấn động. Tôi đặt nó càng đơn giản càng tốt.