如何使用分组来确认完整的双射(一对一对应)

时间:2018-03-22 23:04:44

标签: sql sqlalchemy

我遇到两个SQL查询问题。

4桌:球员,任务,完成记录,任务分配

球员和任务之间的多对多关系

玩家A被分配了3个任务。

玩家B被分配了2个任务。

玩家C被分配了2个任务。

一个查询应该返回完成所有已分配任务的玩家。

另一个查询应该返回未完成所有已分配任务的玩家。

'archipelagoes.'

查询不起作用,因为// query 1 select * from players join mission_assignment on players.id=mission_assignment.player_id group by players.id having count(mission_assignment.mission_id not in(mission_id list in completion_record))=0 // query 2 select * from players join mission_assignment on players.id=mission_assignment.player_id group by players.id having count(mission_assignment.mission_id not in(mission_id list in completion_record))>0 中的子查询是动态的。

是否可以将player_id传递给子查询?

任务

id name

1 1st

2 2nd

3 3rd

玩家

id name

1 A

2 B

3 C

mission_assignment(关联表)

player_id mission_id

1 1

1 2

1 3

2 2

2 3

3 1

3 3

completion_record

player_id mission_id

1 1

1 2

1 3

2 2

2 3

3 1

1 个答案:

答案 0 :(得分:0)

These hinge on you adding an identity column to MissionAssignments table (it essentially becomes a single Id for the combination of player_id/mission_id). You could probably add one to Completion Record as well. They will come in handy for future queries.

Try this for completed missions:

SELECT ma.Id, ma.player_id , ma.mission_id FROM MissionAssignment ma
INTO #CompletedMissions                  -- DROP TABLE #CompletedMissions
INNER JOIN CompletionRecord cr
  ON ma.player_id = cr.player_id AND ma.mission_id = cr.mission_id

You can select any or all from the temp table for display. You could also join to players and missions to get names from ids. Remove the "INTO" line to get query results instead of putting it into a temp table.

AND:

SELECT ma.Id, ma.player_id, p.name, m.name
FROM MissionAssignment ma
INNER JOIN Players p
  ON ma.player_id = p.Id
INNER JOIN Missions m
  ON ma.mission_id = m.Id
WHERE ma.Id NOT IN (SELECT id FROM #CompletedMissions)

This will get you Assigned, but Not Completed missions with playername and mission name.

Also try this for Not Completed, but I'm not 100% on the results from this one:

SELECT p.name, m.name
FROM Players p
INNER JOIN MissionAssignment ma
  ON p.id = ma.player_id
INNER JOIN Mission m
  ON m.id = ma.mission_id
RIGHT JOIN CompletionRecord cr
  ON ma.player_id = cr.player_id AND cr.mission_id = ma.mission_id