postgresql:如果两个值都不在表a中,则在表b中插入两个值

时间:2017-02-03 16:09:41

标签: database postgresql

我正在做一个作业,我要制作锦标赛结果的sql-database。可以通过他们的名字添加玩家,并且当数据库具有至少两个或更多尚未被分配到比赛的玩家时,两个玩家应该彼此匹配。

例如,如果表格当前为空,我将Joe添加为播放器。然后我还添加了James,因为该表有两个参与者,他们也不在matches - 表中,matches - 表中的新行创建了他们的{{ 1}}设置为left_player_P_id和right_player_P_id。

我认为创建一个函数和一个触发器是个好主意,这样每次将一行添加到p_id - 表时,sql代码都会运行并在{{{ 1}}根据需要。我愿意接受其他方式。

我尝试了多种不同的方法,包括SQL - Insert if the number of rows is greater thanUsing IF ELSE statement based on Count to execute different Insert statements,但我现在感到茫然。

有问题的代码:

此方法返回语法错误。

player

替代方法(仍有问题的代码):

这种方法似乎更有前景(但可读性更低)。但是,即使matches内没有返回任何行,它也会插入。

IF ((select count(*) from players_not_in_any_matches) >= 2)
  begin
    insert into matches values (
      (select p_id from players_not_in_any_matches limit 1),
      (select p_id from players_not_in_any_matches limit 1 offset 1)
      )
  end;

where not exists

视图

insert into matches (left_player_p_id, right_player_p_id)
select
    (select p_id from players_not_in_any_matches limit 1),
    (select p_id from players_not_in_any_matches limit 1 offset 1)
where not exists (
    select * from players_not_in_any_matches offset 2
);

1 个答案:

答案 0 :(得分:1)

尝试:

insert into matches (left_player_p_id, right_player_p_id)
select p1.p_id, p2.p_id
from players p1
join players p2
on p1.p_id <> p2.p_id
and not exists(
   select 1 from matches m
   where p1.p_id in (m.left_player_p_id, m.right_player_p_id)
)
and not exists(
   select 1 from matches m
   where p2.p_id in (m.left_player_p_id, m.right_player_p_id)
)
limit 1

使用LEFT JOIN可以进一步简化上述查询中的反连接(非存在运算符):

insert into matches (left_player_p_id, right_player_p_id)
select p1.p_id, p2.p_id
from players p1
join players p2
left join matches m1
on p1.p_id in (m1.left_player_p_id, m1.right_player_p_id)
left join matches m2
on p2.p_id in (m2.left_player_p_id, m2.right_player_p_id)    
where m1.left_player is null
  and m2.left_player is null
limit 1

但在我看来,前一个查询更具可读性,而后一个查询看起来很棘手。