将 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
我有一个 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