将 table 中的两行合并为一行

Combining two rows from a table into one

我有一个 table,我注意到唯一约束设置不正确,并且重复的行已进入 table。

我设置了这个 sqlfiddle:http://sqlfiddle.com/#!15/c4a5d/1/0

create table foo (
bad_id INT NOT NULL,
real_id INT NOT NULL,
a TEXT,
b TEXT
);

insert into foo values
(1, 1, 'a1', null),
(2, 1, null, 'b1'),
(3, 1, null, null),
(4, 2, 'a22', 'b2'),
(5, 2, 'a2', 'b22'),
(6, 3, null, null);

我正在尝试通过合并值来修复 table。如果存在较新的行,我想采用这些值(应该是更新而不是插入)

我想要的最终结果是这样的,在 real_id

上独一无二
3 | 1 | 'a1' | 'b1'
5 | 2 | 'a2' | 'b22'
6 | 3 | null | null

基本上我希望最终结果看起来好像第一行是插入的,而具有相同 real_id 的任何后续行都是部分更新

我可以使用哪种查询来创建最终结果集?

我正在使用 Postgres 9.4。

如果在 sql 中需要执行此操作的内容很糟糕或渐近性能非常差,我应该能够通过将所有行拉入代码(大约 25000)然后执行手动合并。不过在 sql 中似乎应该可行。

从代码的角度来看,它看起来像一个 fold 操作,那么 WITH RECURSIVE cte 可以帮助我吗?

试试这个:

  select max(bad_id),
    split_part(string_agg(a,'__SPLITER__' order by bad_id DESC),'__SPLITER__',1)
    ,split_part(string_agg(b,'__SPLITER__' order by bad_id DESC),'__SPLITER__',1)  
  from foo group by real_id

如果 a 和 b 是时间戳:

    select max(bad_id),
        split_part(string_agg(a::character varying,'__SPLITER__' order by bad_id DESC),'__SPLITER__',1)::timestamp,
        split_part(string_agg(b::character varying,'__SPLITER__' order by bad_id DESC),'__SPLITER__',1)::timestamp  
    from foo group by real_id

整数相同:split_part(string_agg(a::character varying ...,1)::integer