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

Chọn các ô hàng làm cột mới

Câu hỏi này khó hơn rất nhiều để giải quyết hơn bạn có thể mong đợi. Nỗ lực của bạn với crosstab() đã nhắm đúng hướng. Nhưng để gán tên cột động, bạn cần thêm SQL động: EXECUTE trong một hàm plpgsql.

Thay đổi kiểu dữ liệu của cột infos.type từ text tới regtype để ngăn chặn việc đưa vào SQL và các lỗi khác. Ví dụ:bạn có kiểu dữ liệu number , không phải là kiểu dữ liệu PostgreSQL hợp lệ. Tôi đã thay thế nó bằng numeric , vì vậy nó có thể hoạt động.

Bạn có thể đơn giản hóa nhiệm vụ bằng cách tránh các tên cột cần trích dẫn kép. Giống như nume_anterior thay vì "nume anterior" .

Bạn có thể muốn thêm một cột row_id vào bảng của bạn info_data để đánh dấu tất cả các phần tử của một hàng. Bạn cần nó cho crosstab() và nó cho phép bạn bỏ qua các cột có NULL các giá trị. crosstab() hàm có hai tham số có thể giải quyết các cột bị thiếu. Tôi tổng hợp cột bị thiếu với biểu thức (d.id-1)/13 bên dưới - phù hợp với dữ liệu trong ví dụ của bạn.

Bạn cần cài đặt bảng mô-đun bổ sung (một lần cho mỗi cơ sở dữ liệu):

CREATE EXTENSION tablefunc;

Tìm giải thích và liên kết bổ sung trong câu trả lời có liên quan này .

Hàm này sẽ thực hiện những gì đang tìm kiếm:

CREATE OR REPLACE FUNCTION f_mytbl()
  RETURNS TABLE (id int
, nume text           , prenume text       , cnp numeric
, "nume anterior" text, "stare civila" text, cetatenie text
, rezidenta text      , adresa text        , "tip act" text
, "serie ci" text     , "numar ci" text    , "data eliberarii" text
, "eliberat de" text)
  LANGUAGE plpgsql AS
$BODY$
BEGIN

RETURN QUERY EXECUTE $f$
SELECT *
FROM   crosstab(
    'SELECT (d.id-1)/13 -- AS row_id
          , i.id, d.value
     FROM   infos i
     JOIN   info_data d ON d.id_info = i.id
     ORDER  BY 1, i.id',

    'SELECT id
     FROM   infos
     ORDER  BY id'
    )
AS tbl ($f$ || 'id int,
, nume text           , prenume text       , cnp numeric
, "nume anterior" text, "stare civila" text, cetatenie text
, rezidenta text      , adresa text        , "tip act" text
, "serie ci" text     , "numar ci" text    , "data eliberarii" text
, "eliberat de" text)';

END;
$BODY$;

Gọi:

SELECT * FROM x.mytbl();

Đừng nhầm lẫn với báo giá đô la .

BTW:Tôi đã tạo danh sách cột bằng câu lệnh này:

SELECT 'id int,' || string_agg(quote_ident(name) || ' ' || type
                              ,', ' ORDER BY i.id) 
FROM   infos i;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Multi-DC PostgreSQL:Thiết lập nút chờ tại một vị trí địa lý khác qua VPN

  2. Chạy PostgreSQL CLI (psql) trong tập lệnh bash mà không có lời nhắc mật khẩu?

  3. pg_dump:làm thế nào để cài đặt trên Amazon Linux cho PostgreSQL 9.5.2?

  4. Cách nhận hệ điều hành máy chủ theo giờ địa phương trong tất cả các phiên bản Postgres

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