将列分组为一行,忽略 postgreSQL 中的空值

Posted

技术标签:

【中文标题】将列分组为一行,忽略 postgreSQL 中的空值【英文标题】:Group columns into a row, ignoring nulls in postgreSQL 【发布时间】:2019-08-05 14:24:04 【问题描述】:

我正在尝试将列连接成一行。这是我的数据示例:

 name |  x   |  y   | value
------+------+------+-------
  A   |  N   | null |   x
  A   | null |  M   |   y
  B   |  O   | null |   x
  B   | null |  P   |   y

我可以改为使用以下方法:

 name | value | data
------+-------+------
  A   |   x   |  N
  A   |   y   |  M
  B   |   x   |  O
  B   |   y   |  P

这就是我想要得到的:

 name |  x   |  y   
------+------+------
  A   |  N   |  M
  B   |  O   |  P

我尝试过分组,但由于无法按单个列进行分组,因此无法正确分组。

我尝试过的其他方法是将表连接到自身 n 次,其中 n = 我想要获得的列数,但那不是最理想的,并且需要相当长的时间来运行。

我从查询中创建了第一个示例,因为这样我就可以更接近我想要的结果,但这样做可能会使事情变得复杂。

编辑:我想指出xy 列是varchars,所以我不能在它们上使用max。我已经用更接近我所拥有的示例更正了示例数据。 value 列是我放置数据的位置(所有内容都来自外部表)。

【问题讨论】:

如果name = 'A' 的第三行的值为x,该怎么办? @a_horse_with_no_name 在这种情况下这是不可能的,所以这不是问题! "我想指出 x 和 y 列是 varchars,所以我不能对它们使用 max" - 当然可以。是什么让您认为您不能在 varchar 列上使用 min() 这是一个与原来的问题完全不同的问题。 @a_horse_with_no_name 因为它们有字符,而不是整数。我可能错了,但你不能对 'hello' 这样的值做最大值。 【参考方案1】:

你应该展示你的尝试。这是一个简单的聚合:

select name, max(x) as x, max(y) as y
from t
group by name;

很可能,您使用某种聚合查询生成了这些数据。该查询没有正确的 group by 键,可能很容易修复。

【讨论】:

【参考方案2】:

您可以按名称分组,然后从每个组中获取最大值,如:

select
  name, max(x), max(y)
from t
group by name

【讨论】:

【参考方案3】:

创建一个 CTE 并将表连接到自身以将 y 值插入 x 值行,从而为您提供所需的列表。

WITH CTE AS
(
SELECT 
    table1.name,table1.x,table12.y
FROM table1
left join (select name,y from table1 where value = 'y') as table12 on table1.name = table12.name
WHERE value = 'x'
)
select * from CTE

【讨论】:

以上是关于将列分组为一行,忽略 postgreSQL 中的空值的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL 中的分组限制:显示每个组的前 N ​​行,但仅当这些行中的第一行等于特定数据时

PostgreSQL 将列转换为行?转置?

PostgreSQL 数据库中表中的空列有多宽? [复制]

如何将 2 行或更多行的数据添加到 postgresql 中的一行

如何使用 SQLAlchemy 将列默认设置为 PostgreSQL 函数?

如何忽略 Spring JPQL 中的空参数?