我正在做一个作业,我要制作锦标赛结果的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 than和Using 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
);
答案 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
但在我看来,前一个查询更具可读性,而后一个查询看起来很棘手。