Postgres:如何聚合一行以报告具有最高值的列名?

Posted

技术标签:

【中文标题】Postgres:如何聚合一行以报告具有最高值的列名?【英文标题】:Postgres: how can I aggregate a row to report the column name with the highest value? 【发布时间】:2016-02-10 03:26:26 【问题描述】:

对于 postgres 表中的每一行,我正在尝试确定具有最高值的列的名称:

输入

 row_id | type1 | type2 | type3 
--------+-------+-------+-------
 A      |     2 |    44 |     7
 B      |   321 |     5 |    73
 C      |   302 |   620 |     9

期望的输出

 row_id | max_type | max_value 
--------+----------+-----------
 A      | type2    |        44
 B      | type1    |       321
 C      | type2    |       620

这类似于this SQL Server question,但CROSS APPLY 似乎是not be precisely related to anything in postgres。

我试过这个,但它遍历整个表,而不是一次一行:

SELECT
  unnest(ARRAY['type1','type2','type3']) AS max_type,
  unnest(ARRAY[type1,type2,type3]) AS max_value
FROM table
ORDER BY max_value DESC
LIMIT 1;

在 postgres 中解决这个问题的正确方法是什么?

【问题讨论】:

【参考方案1】:

DISTINCT ON (row_id)ORDER BY row_id, max_value DESC 一起使用:

SELECT DISTINCT ON (row_id) row_id, max_type, max_value
FROM (
    SELECT
        row_id,
        unnest(ARRAY['type1','type2','type3']) AS max_type,
        unnest(ARRAY[type1,type2,type3]) AS max_value
    FROM a_table
    ) s
ORDER BY row_id, max_value DESC;

 row_id | max_type | max_value 
--------+----------+-----------
 A      | type2    |        44
 B      | type1    |       321
 C      | type2    |       620
(3 rows)

【讨论】:

这太棒了——尽管我不得不承认我真的不明白为什么在不使用明确的LIMIT 1 时它会起作用。

以上是关于Postgres:如何聚合一行以报告具有最高值的列名?的主要内容,如果未能解决你的问题,请参考以下文章

如何在带有 Postgres 的动态框架中使用窗口函数中的列值?

使用 group by 聚合的 postgres 查询解释

如何通过 Eloquent 中具有多对多关系的外部表中的列聚合进行分组?

如何存储一行中的变量以在 Pentaho 水壶中的后续行中使用?

如何在聚合中包含下一组的第一行?

将相同的行组聚合为一行