I am recording sports match data in the form of 3 tables:
- matches (id, start_time)
- match_teams (id, match_id, team_id, score)
- match_players (id, match_id, team_id, player_id)
Each match consists of several teams, each team consists of several players (effectively a list of lists). With team_id and player_id as foreign keys on the teams and players table respectively.
Using the above structure, I need to insert into the matches table first and use the returned id to pass into match_teams and match_players.
Following this question I am using the following CTE to accomplish this where I am inserting one match:
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);
I want to insert multiple matches at once in one query. I am using offset and limit to select the right match id for the players/ teams.
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
This works, but it seems like a bit of a hacky solution. Is there a best practice way to do this?
Update I've realised I have some redundant columns. I've fixed this up, but I don't think it changes the question significantly. My question is more like "is using offset and limit like this best practice?"
selectswithoffset. Although I'm pretty sure that this one query solution is not a best pratice at all.