【发布时间】:2016-02-03 16:04:59
【问题描述】:
我正在以 3 个表格的形式记录运动比赛数据:
- 匹配(id,start_time)
- match_teams(id、match_id、team_id、得分)
- match_players(id、match_id、team_id、player_id)
每场比赛由几支球队组成,每支球队由几名球员组成(实际上是一个列表)。以team_id和player_id分别作为teams和players表的外键。
使用上面的结构,我需要先插入到matches表中,并使用返回的id传入match_teams和match_players。
在this question 之后,我正在使用以下 CTE 来完成此操作,我正在插入一个匹配项:
WITH a AS (INSERT INTO matches (start_time)
VALUES ('"0001-01-01T00:00:00+00:00"')
RETURNING id),
b AS (INSERT INTO match_teams (match_id, team_id, score)
VALUES
((SELECT id FROM a), 5, 1),
((SELECT id FROM a), 6, 2))
INSERT INTO match_players (match_id, team_id, player_id)
VALUES
((SELECT id FROM a), 5, 3),
((SELECT id FROM a), 5, 4),
((SELECT id FROM a), 6, 5)
((SELECT id FROM a), 6, 6);
我想在一个查询中一次插入多个匹配项。我正在使用 offset 和 limit 为球员/球队选择正确的比赛 ID。
WITH a AS (INSERT INTO matches (start_time)
VALUES
('"0001-01-01T00:00:00+00:00"'), -- 1st match
('"0001-01-01T00:00:00+00:00"') -- 2nd match
RETURNING id),
b AS (INSERT INTO match_teams (match_id, team_id, score)
VALUES
((SELECT id FROM a OFFSET 0 LIMIT 1), 5, 1), -- 1st match
((SELECT id FROM a OFFSET 0 LIMIT 1), 6, 2), -- 1st match
((SELECT id FROM a OFFSET 1 LIMIT 1), 5, 2), -- 2nd match
((SELECT id FROM a OFFSET 1 LIMIT 1), 6, 1)) -- 2nd match
INSERT INTO match_players (match_id, team_id, player_id)
VALUES
((SELECT id FROM a OFFSET 0 LIMIT 1), 5, 3), -- 1st match
((SELECT id FROM a OFFSET 0 LIMIT 1), 6, 4), -- 1st match
((SELECT id FROM a OFFSET 1 LIMIT 1), 5, 5), -- 2nd match
((SELECT id FROM a OFFSET 1 LIMIT 1), 6, 6); -- 2nd match
这可行,但它似乎有点像一个 hacky 解决方案。有没有最佳实践方法来做到这一点?
更新我意识到我有一些多余的列。我已经解决了这个问题,但我认为它不会显着改变问题。我的问题更像是“像这种最佳做法一样使用偏移量和限制吗?”
【问题讨论】:
-
您可以使用序列(nextval, currval)来避免
selects和offset。虽然我很确定这个查询解决方案根本不是最佳实践。
标签: sql postgresql