PostgreSQL如何将SQL查询的两列键值结果转为列名对应值的宽表格式
行转列SQL实现方案
通用标准SQL写法(兼容所有SQL数据库)
不需要依赖数据库特有语法或扩展,直接通过条件判断+聚合实现,是最稳妥的实现方式:
SELECT MAX(CASE WHEN name = 'log_directory' THEN setting END) AS log_directory, MAX(CASE WHEN name = 'log_filename' THEN setting END) AS log_filename, MAX(CASE WHEN name = 'log_line_prefix' THEN setting END) AS log_line_prefix, MAX(CASE WHEN name = 'logging_collector' THEN setting END) AS logging_collector, MAX(CASE WHEN name = 'log_destination' THEN setting END) AS log_destination FROM pg.settings WHERE name IN ('log_destination', 'logging_collector', 'log_directory', 'log_filename', 'log_line_prefix');
说明:由于pg.settings中每个name只有唯一对应的一行记录,使用MAX/MIN这类聚合函数均可正常取到对应值,最终会把多行键值结果聚合为单行多列的格式,列顺序完全符合需求。
PostgreSQL特有crosstab函数写法
如果是PostgreSQL环境,也可以使用专门的行转列函数crosstab实现,适合待转换列数量较多的场景,需要先启用tablefunc扩展:
-- 首次使用需要先加载扩展 CREATE EXTENSION IF NOT EXISTS tablefunc; -- 行转列查询 SELECT * FROM crosstab( 'SELECT 1 AS row_id, name, setting FROM pg.settings WHERE name IN (''log_directory'', ''log_filename'', ''log_line_prefix'', ''logging_collector'', ''log_destination'') ORDER BY name = ''log_directory'' DESC, name = ''log_filename'' DESC, name = ''log_line_prefix'' DESC, name = ''logging_collector'' DESC, name = ''log_destination'' DESC' ) AS ct(row_id int, log_directory text, log_filename text, log_line_prefix text, logging_collector text, log_destination text);
内容的提问来源于stack exchange,提问作者Murtuza Z
相关产品推荐
相关产品推荐

