如何使用外键约束跨模式匹配同一表中的行

时间:2014-12-17 08:36:43

标签: sql postgresql

Postgres版本信息:"在x86_64-unknown-linux-gnu上的PostgreSQL 9.1.14,由gcc(GCC)4.4.7 20120313(Red Hat 4.4.7-4)编译,64位"

我有一个表T,其中列Id,Field1,Field2有两种不同的模式(虽然这并不重要),S和S'。表T有一个参考表F,它包含字段Id,Field1,其中Id是表T的外键。

CREATE TABLE S.T
(
  Id character varying(36) NOT NULL,
  FieldA character varying(32) NOT NULL,
  FieldB  character varying(250),
  CONSTRAINT pk_T PRIMARY KEY (Id)
)

CREATE TABLE S.F
(
  Id character varying(36) NOT NULL,
  Field1 character varying(36) NOT NULL,
  CONSTRAINT pk_F PRIMARY KEY (Id, Field1),
  CONSTRAINT fk_F_T FOREIGN KEY (Id)
      REFERENCES S.T(Id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)

同样在模式S'我们有桌子T'和F'。请注意,T和F之间存在1..n关系,即F中的多行具有相同的Id。

我想创建一个匹配T和T'之间行的查询。基于F。

中的Field1值
Example in Schema S:
T.Id | T.FieldA | T.FieldB      F.Id | F.Field1
--------------------------      ---------------
1    | A        | B             1    | XYZ
2    | C        | D             1    | WVU 
                                2    | STR
                                2    | PQR

Example in Schema S':
T'.Id | T'.FieldA | T'.FieldB      F'.Id | F'.Field1
--------------------------      ---------------
1'    | A'        | B'             1'    | XYZ
2'    | C'        | D'             1'    | WVU 
                                   2'    | STR
                                   2'    | PQR

如何使查询与T中的第1行匹配第1行'来自T'因为它们具有相同的外键信息XYZ和WVU,并且类似于来自T的第2行和第2行'来自T'?换句话说,行由它们在F中的匹配行唯一定义。

当然,他们查询并不像上面那样简单:行在T和T'之间匹配。通过F(和F',分别)和T.FieldA中的信息,然后成功匹配,我将需要更新T' .FieldB。

在期待中感谢你。

1 个答案:

答案 0 :(得分:0)

你的示例数据 - 我已经重命名了一些东西以使生活更轻松。

create schema a; create schema b;
create table a.t (id int primary key ,a text,b text);
insert into a.t values(1,'A','B'),(2,'C','D');
create table a.f (id int references a.t(id),field1 text);
insert into a.f values (1,'XYZ'),(1,'WVU'),(2,'STR'),(2,'PQR');
create table b.t (id int primary key ,a text,b text);
insert into b.t values(11,'A''','B'''),(22,'C''','D''');
create table b.f (id int references b.t(id),field1 text);
insert into b.f values (11,'XYZ'),(11,'WVU'),(22,'STR'),(22,'PQR');

加入:

SELECT * FROM a.t 
  JOIN a.f ON a.t.id = a.f.id
  JOIN b.f ON a.f.field1 = b.f.field1 
  JOIN b.t ON b.t.id = b.f.id 

更新?:

UPDATE b.t 
  SET b=b.t.b||'('||a.t.id||')'
  FROM a.f 
    JOIN b.f ON a.f.field1 = b.f.field1 
    JOIN a.t ON a.t.id = a.f.id 
  WHERE b.t.id = b.f.id
;

清理

drop schema a cascade;drop schema b cascade;