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

Chọn nhiều giá trị max () bằng cách sử dụng một câu lệnh SQL

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()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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tự cấp phép tài khoản người dùng trong PostgreSQL thông qua quyền truy cập ẩn danh không đặc quyền

  2. Tối ưu hóa PostgreSQL để kiểm tra nhanh

  3. Cách justify_interval () hoạt động trong PostgreSQL

  4. [Video] Tích hợp dữ liệu với PostgreSQL

  5. Tìm các hàng có nhiều trường trùng lặp với Active Record, Rails &Postgres