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;