2015-11-03 73 views
4

跨越3個表插入多個行中1次的查詢我記錄運動在3代表的形式匹配數據:使用返回的ID

  • 匹配(ID,START_TIME)
  • match_teams(ID ,match_id,TEAM_ID,得分)
  • match_players(ID,match_id,TEAM_ID,player_id)

每場比賽由幾支球隊組成,每支球隊由幾名球員組成(實際上是一份列表)。將team_id和player_id分別作爲球隊和球員表上的外鍵。

使用上述結構,我需要先插入匹配的表,然後使用返回的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); 

我想一次在一個查詢中插入多場比賽。我使用偏移和限制來爲球員/球隊選擇正確的比賽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 

這有效,但它似乎有點哈克解決方案。有沒有最佳實踐方法來做到這一點?

更新我意識到我有一些冗餘列。我已經解決了這個問題,但我認爲它不會顯着改變這個問題。我的問題更像是「像這種最佳實踐一樣使用偏移和限制?」

+0

你可以使用序列(NEXTVAL,CURRVAL),以避免與'offset'那些'selects'。雖然我很確定這個查詢解決方案根本不是最佳實踐。 –

回答

3

使用offset和limit這樣的最佳實踐?

當然不是。這非常低效,使用起來非常不方便,特別是對於大量的比賽。

您可以使用row_number()選擇合適的id加入teamsplayersteams

with teams (rn, team_ids, scores) as (
    values 
     (1, array[5, 6], array[1, 2]), -- match #1 in this query 
     (2, array[5, 6], array[2, 1]) -- match #2 in this query 
    ), 
players (rn, team_ids, player_ids) as (
    values 
     (1, array[5, 5, 6, 6], array[3, 4, 5, 6]), 
     (2, array[5, 5, 6, 6], array[3, 4, 5, 6]) 
    ), 
ins_matches as (
    insert into matches (start_time) 
    values 
     ('"0001-01-01t00:00:00+00:00"'), 
     ('"0001-01-01t00:00:00+00:00"') 
    returning id 
    ), 
matches as (
    select id, row_number() over (order by id) rn 
    from ins_matches  -- rn - number of match in this query 
    ), 
ins_teams as (
    insert into match_teams (match_id, team_id, score) 
    select id, unnest(team_ids), unnest(scores) 
    from matches 
    join teams using(rn) 
    ) 
insert into match_players (match_id, team_id, player_id) 
select id, unnest(team_ids), unnest(player_ids) 
from matches 
join players using(rn); 
0

在我來說,我有route_sourcesroutes

  • route_sourcesroute_source_id作爲PK
  • routesroute_source_id爲FK

-- GOT ID TO ROUTE_SOURCES FROM SEQUENCE 
int_route_source_id = nextval('traffic.route_sources_route_source_id_seq'::regclass); 

-- CREATE NEW RECORD FOR ROUTE_SOURCES 
INSERT INTO traffic.Route_Sources 
    (route_source_id, sql, ini_avl_id, ini_link_id) 
VALUES 
    (int_route_source_id, strSQL, A.avl_id, A.link_id, ini_offset); 

-- CREATE THE ROUTE 
INSERT INTO traffic.Routes 
    (route_source_id, seq_id, node_id, link_id, cost)    
SELECT int_route_source_id, seq, id1 AS node, id2 AS edge, cost::numeric(11,4) 
    FROM pgr_trsp;