sql - 如何选择多个现有的列名并将其分组为 1 列?

标签 sql postgresql grouping

我正在使用 posgresql。如何将列名分组到一个列中,并将其值分组到现有表中的另一列中?然后用它来创建一个临时表?

现有表:

+---------+----------+---------+----------+
|  col_a  |   col_b  |  col_c  |   col_d  |
+---------+----------+---------+----------+
|       1 |        2 |       3 |        4 |
+---------+----------+---------+----------+

临时表:

+----------+----------+
|categories|   value  |
+----------+----------+
|   col_a  |        1 |  
|   col_b  |        2 |
|   col_c  |        3 | 
|   col_d  |        4 | 
+----------+----------+

下面是生成临时表的sql语句。

CREATE TEMPORARY table myTable_temp
(
    categories Varchar (50),
    value float8
);

但我仍然坚持尝试将特定列名称分组到一列中,并将其值放在另一列中,但仍将它们链接在一起。

最佳答案

此过程也称为 UNPIVOT,可以在 Postgres 中像这样完成:

select up.*
from the_table
  cross join lateral (
    values 
      ('col_a', col_a),
      ('col_b', col_b),
      ('col_c', col_c),
      ('col_d', col_d)
  ) as up(category, value);

请注意,这仅适用于所有列都具有相同数据类型的情况。

如果您不介意丢失数据类型(或者如果列有不同的类型并且您无论如何都需要将它们转换为 text),您可以使用 JSON 函数使其动态化:

select up.*
from the_table tt
  cross join lateral jsonb_each_text(to_jsonb(tt)) as up;

如果您知道所有值都可以转换为同一类型,您可以使用:

select up.category, 
       up.value::float
from the_table tt
  cross join lateral jsonb_each_text(to_jsonb(tt)) as up(category, value);

在线示例:https://rextester.com/SHOY36906


如果您需要将“值”列与表的原始主键匹配,您可以这样做(假设主键名为id)

select tt.id, up.*
from the_table tt
  cross join lateral jsonb_each_text(to_jsonb(tt) - 'id') as up(category, value)
order by tt.id;

在线示例:https://rextester.com/MSXD50860

关于sql - 如何选择多个现有的列名并将其分组为 1 列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58429322/

相关文章:

c - 文件中的 Doxygen 组模块

SQL:如何搜索连续事件?

php - if else 查询更新某些表列

mysql - 如何使用sql存储过程在一些字符(varchar)之后添加尾随空格?

python - Pandas 分组并按索引计数排序

ruby - 在 Ruby 中按身份分组

c# - NVarChar 到 C# 数据类型

java - SimpleDateFormat 返回 12 小时前 5.30 到 6.30 之间的时间

sql - 如何在 SQL 中选择 FROM..WHERE 然后加入?

postgresql - 不同的时区输出错误的值