我有一个Postgres数据表,如下所示(例如):
╔════╦═══════════╦════════════╗ ║ ID ║ FieldName ║ FieldValue ║ ╠════╬═══════════╬════════════╣ ║ 66 ║ PO# ║ 11111111 ║ ║ 66 ║ Zip ║ 01810 ║ ║ 66 ║ Badge ║ 22222222 ║ ║ 67 ║ PO# ║ 7777777 ║ ║ 67 ║ Zip ║ 02144 ║ ║ 67 ║ Badge ║ 99999999 ║ ╚════╩═══════════╩════════════╝
我的问题是如何将此表转换为如下所示的新表:
╔════╦══════════╦════════╦══════════╗ ║ ID ║ Field1 ║ Field2 ║ Field3 ║ ╠════╬══════════╬════════╬══════════╣ ║ 66 ║ 11111111 ║ 01810 ║ 22222222 ║ ║ 66 ║ 7777777 ║ 02144 ║ 99999999 ║ ╚════╩══════════╩════════╩══════════╝
我需要完全使用Postgres语法完成。理想情况下,我还能够动态地计算出有多少字段,但这是次要的需求。目前,假设有三个字段,我需要将它们转换为名为Field#的新列。
答案 0 :(得分:1)
使用tablefunc模块中的crosstab()
函数。详细说明和链接(请先阅读!):
PostgreSQL Crosstab Query
您的查询可能如下所示:
SELECT *
FROM crosstab(
'SELECT "ID", "FieldName", "FieldValue"
FROM tbl
ORDER BY 1'
,$$VALUES ('PO#'::text), ('Zip'), ('Badge')$$
) AS ct ("Section" text, "Field1" int, "Field2" int, "Field3" int);
要dynamically figure out how many fields there were
,您必须动态构建上述语句。 SQL要求知道返回类型。在这个相关问题下的更多细节:
Dynamic alternative to pivot with CASE and GROUP BY