我有三个表结构:tournament
,group
和team
。 tournament
和group
表格具有一对多关系,而group
和team
有一个一对一许多关系,如下所示。
如何将tournament_id
的{{1}}值复制到group
表的group_tournament_id
?
我正在寻找一个能够使用像
这样的创建语句来实现这个目标的答案team
当然这不起作用,因为为了引用它必须是唯一的东西,在这种情况下,tournament_id不是唯一的
当我插入create table team (
id serial primary key,
group_id int references group,
group_tournament_id int references group(tournament_id)
);
团队tournament_id
时,我需要一种标准方式将group
的值从group_tournament_id
复制到'团队'表的group_id inside
编辑:不再需要在symfony中回答,只需postgreSQL就可以了
答案 0 :(得分:5)
您应该直接使用teams
到tournaments
的引用。使用触发器从groups.
自动获取相应的引用(请注意,引用不是必需的,因为在查询中始终可以从tournament_id
获取groups
。我假设此引用是简化一些查询。)
我稍微修改了表和列的名称(group
不能是表的名称)。
表:
create table tournaments (
tournament_id serial primary key);
create table groups (
group_id serial primary key,
tournament_id int references tournaments);
create table teams (
team_id serial primary key,
group_id int references groups,
tournament_id int references tournaments);
触发:
create or replace function before_insert_or_update_on_teams()
returns trigger language plpgsql as $$
begin
new.tournament_id = (
select tournament_id
from groups
where group_id = new.group_id
limit 1);
return new;
end $$;
create trigger before_insert_or_update_on_teams
before insert or update on teams
for each row execute procedure before_insert_or_update_on_teams();
测试:
insert into tournaments values (default), (default);
insert into groups values (default, 2);
insert into teams values (default, 1, null);
select * from teams;
team_id | group_id | tournament_id
---------+----------+---------------
1 | 1 | 2
(1 row)
答案 1 :(得分:3)
您可以使用识别关系:
这会生成传播的密钥"一直向下,所以你得到delete
,保证指向与父组相同的锦标赛。
请注意,我使用team.tournament_id
(不是group_no
)作为命名惯例,表示它不能单独识别该组,而是与group_id
结合使用。同上tournament_id
。
但这使插入变得复杂。您不能再让数据库为您的组或团队生成下一个自动递增的ID(因为您现在使用值的组合识别它,而不仅仅是一个值),但您可以轻松地手动执行 - 例如插入team_no
时,将group
分配给新的SELECT MAX(group_no) + 1 FROM group WHERE tournament_id = ...
,并为该小组分配类似内容。
顺便说一下,如果你还需要它,可以另外到surrogate keys(图表中的group_no
)。
答案 2 :(得分:1)
您可以使用SELECT
通过INSERT
或UPDATE
提供值:
INSERT INTO "teams" ("group_id", "tournament_id")
SELECT $1, "groups"."tournament_id"
FROM "groups" WHERE ("groups"."id" = $1)
RETURNING "id"
这是我用来让Postgres在没有(不一致的)双重查询的情况下插入外键的ID(从组中选择,插入到团队中)。