如何选择失败排除约束的行

时间:2019-02-12 15:01:23

标签: postgresql

我有一个表,其中有行(源),我试图将其插入另一个表(目标)。目标具有适当的排除约束。但是,当我这样做时,某些行无法通过排除约束。我希望能够在源代码中选择这些排除排除约束的行。这可能吗?

create table target(
id bigint primary key 
,external_data_source_id bigint not null 
,external_id text not null 
,external_id_domain_id bigint not null 
,internal_id bigint not null 
,valid_period tstzrange not null
,EXCLUDE USING gist (external_data_source_id with = , external_id_domain_id with =, internal_id with =, external_id with =, valid_period WITH &&) 
);

create table source(
id bigint primary key 
,external_data_source_id bigint not null 
,external_id text not null 
,external_id_domain_id bigint not null 
,internal_id bigint not null 
,valid_period tstzrange not null
);

insert into source
select 1,1,'text',1,1,tstzrange('2000-01-01','2001-01-01');

insert into source
select 2,1,'text',1,1,tstzrange('2000-01-01','2001-01-01');

insert into source
select 1,'text',1,1,tstzrange('2002-01-01','2004-01-01');

insert into target
select * from source;

给予

Error: ERROR: conflicting key value violates exclusion constraint "target_external_data_source_id_external_id_domain_id_inter_excl"
  Detail: Key (external_data_source_id, external_id_domain_id, internal_id, external_id, valid_period)=(1, 1, 1, text, ["2000-01-01 00:00:00+01","2001-01-01 00:00:00+01")) conflicts with existing key (external_data_source_id, external_id_domain_id, internal_id, external_id, valid_period)=(1, 1, 1, text, ["2000-01-01 00:00:00+01","2001-01-01 00:00:00+01")).
SQLState:  23P01
ErrorCode: 0

我想选择源中未能通过此排除约束的行。

1 个答案:

答案 0 :(得分:2)

您可以在存在查询中使用排除约束中的条件:

select s1.*
from source s1
where exists (select * 
              from source s2
              where (s2.external_data_source_id, s2.external_id_domain_id, 
                     s2.internal_id, s2.external_id)  
                     = (s1.external_data_source_id, s1.external_id_domain_id, 
                        s1.internal_id, s1.external_id)
                and s1.valid_period && s2.valid_period
                and s1.id <> s2.id
              );

在线示例:https://rextester.com/PDOE78609