【问题标题】:Merge Multiple records into a single record将多条记录合并为一条记录
【发布时间】:2017-02-24 11:11:48
【问题描述】:

我有以下查询,它为单个 id 生成多条记录。我试图弄清楚如何将这些多条记录合并为一条记录:

SELECT DISTINCT id, gender, dateofbirth, city, state, zip
FROM t

这可能会给我以下结果集:

1, M, 2000-01-01, dallas, tx, 12345
1, M, 2000-01-01, NULL, NULL, NULL

我想要的是一条记录:

1, M, 2000-01-01, dallas, tx, 12345

当第二行有不同的数据时,也会出现类似的情况:

1, M, 2000-01-01, dallas, tx, 12345
1, M, 2000-01-01, houston, tx, 67890

在这种情况下,我只想选择其中一条记录并忽略另一条记录,以便每个 id 只有一条记录。

有没有办法在 PostgreSQL 中做到这一点?我试过合并无济于事,想知道是否有办法处理这个问题。

【问题讨论】:

  • 所以你在那个表中没有主键,没有唯一列?
  • 如果1, M, 2000-01-01, NULL, NULL, 456781, M, 2000-01-01, NULL, 'wa', NULL 还有两行(除了您显示的行),您期望什么。您是否总是至少有一行所有列都不为 NULL?

标签: sql postgresql


【解决方案1】:

下面的查询似乎有效,至少对于您的示例数据。看看下面的 Fiddle 进行演示。我使用 MySQL,因为 Fiddle 往往会因任何其他数据库类型而中断。

SELECT t1.*
FROM yourTable t1
INNER JOIN
(
    SELECT id, MAX(city || ', ' || state || ', ' || zip) AS location
    FROM yourTable
    GROUP BY id
) t2
    ON t1.id = t2.id AND
       t1.city || ', ' || t1.state || ', ' || t1.zip = t2.location

SQLFiddle

我使用的技巧是将城市、州和 zip 连接成一个字符串,然后为 id 值组选择最大值。假设不可能从两个不同的地址以某种方式形成相同的字符串,这将起作用。我认为这适用于您的美国地址格式。

【讨论】:

  • 这种方法的唯一问题是它可能会混合来自不同行的数据。
  • @michaJlS 你说的对,我发的太快了。让我们看看我能不能在戈登·林诺夫到来之前解决这个问题。
  • 如果我记得,在 MySQL 中,您不能将任何聚合函数应用于字段 (stackoverflow.com/questions/2197693/…),但我不知道在 psql 中是否以相同的方式工作,也不是真的然后返回。
【解决方案2】:
Select * from 
(select a.*, row_number () over (partition by id order by city desc)rn
From tablename a
) b where rn=1

上述查询将始终返回一条记录作为 id。如果 city 有多个值,一个有值,一个有 null,则查询将获取具有 city 值的记录。

【讨论】:

  • 我喜欢它 - 分区逻辑总是让我陷入循环(不是双关语),但我让这个按预期工作。非常感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2021-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-12
  • 2019-02-18
  • 1970-01-01
相关资源
最近更新 更多