在这个查询中,我必须列出一对具有playerID和playerName的球员,他们为3支球队踢球,一个球员为3支球队踢球,另一对球员必须为3支球队踢球。不能少,不能多。如果两名球员目前没有为任何球队效力,他们也应该被包括在内。查询应该返回(playerID1,playername1,playerID2,playerName2),没有重复,比如如果玩家1的信息在玩家2之前,那么玩家2的信息不应该在玩家1之前。
例如,如果球员A效力于洋基队和红袜队,而球员B效力于洋基队、红袜队和道奇队,我就不应该得到他们。他们都必须为洋基和红袜队效力,而不是为其他人效力。现在,如果球员为任何同一支球队踢球,这个查询就会找到答案。
player(playerID: integer, playerName: string)
team(teamID: integer, teamName: string, sport: string)
plays(playerID: integer, teamID: integer)现在我得到的查询是
SELECT p1.playerID, p1.playerName, p2.playerID, p2.playerName
FROM player p1, player p2, plays
WHERE p1.teamID = p2.teamID AND teamID in.....在这之后,我被困在了如何处理它上。任何关于如何处理这个问题的提示。耽误您时间,实在对不起。
发布于 2013-07-31 11:08:26
我认为最简单的方法是将团队连接在一起,然后根据结果加入。Postgres提供了聚合字符串的函数string_agg():
select p1.playerId, p1.playerName, p2.playerId, p2.playerName
from (select p.playerId, string_agg(cast(p.TeamId as varchar(255)), ',' order by TeamId) as teams,
pp.PlayerName
from plays p join
players pp
on p.playerId = pp.playerId
group by p.playerId
) p1 join
(select p.playerId, string_agg(cast(p.TeamId as varchar(255)), ',' order by TeamId) as teams,
pp.PlayerName
from plays p join
players pp
on p.playerId = pp.playerId
group by p.playerId
) p2
on p1.playerid < p2.playerid and p1.teams = p2.teams;编辑:
您可以在没有string_agg的情况下做到这一点。这个想法是从所有可能的玩家组合的列表开始。
然后,加入使用left outer join的第一个玩家的团队。并通过使用full outer join并匹配车队和司机的名称来加入第二个车队。您需要驱动程序表的原因是为了确保id/名称不会在完整的外连接中丢失:
select driver.playerid1, driver.playerid2
from (select p1.playerId as playerId1, p1.playerName as playerName1,
p2.playerId as playerId2, p1.playerName as playerName2
from players p1 cross join
players p2
where p1.playerId < p2.playerId
) driver left outer join
plays p1
on p1.playerId = driver.playerId full outer join
plays p2
on p2.playerId = driver.playerId and
p2.teamid = p1.teamid
group by driver.playerid1, driver.playerid2
having count(p1.playerid) = count(*) and
count(p2.playerid) = count(*);这将加入团队id中的两名球员(通过排序,因此一对球员只被考虑一次)。然后,当两个玩家的所有行都有非空的Team值时,它就会说有一个匹配。使用等效的having子句可能会更清楚:
having sum(case when p1.playerid is null then 1 else 0 end) = 0 and
sum(case when p2.playerid is null then 1 else 0 end) = 0;当两个球员的球队不匹配时,完整的外部联接将产生NULL值。因此,没有NULL值意味着所有团队都匹配。
发布于 2013-08-01 21:19:29
这是对您的previous question的my answer的改编。
从player p1中选择p1.playerID,p1.playerName,p2.playerID,p2.playerName内加入player p2 ON p1.playerID < p2.playerID
不存在( SELECT teamID FROM plays WHERE playerID = p1.playerID除外SELECT teamID FROM plays WHERE playerID = p2.playerID )
NOT EXISTS ( SELECT teamID FROM plays WHERE playerID = p2.playerID除外SELECT teamID FROM plays WHERE playerID = p1.playerID )
选择p1.playerID、p1.playerName、p2.playerID、p2.playerName FROM player p1内部加入player p2 ON p1.playerID < p2.playerID WHERE不存在( SELECT teamID FROM plays WHERE playerID = p1.playerID除外SELECT teamID FROM plays WHERE playerID = p2.playerID除外)和不存在( SELECT teamID FROM p1.playerID= p2.playerID除外SELECT teamID FROM FROM播放playerID = p1.playerID );
https://stackoverflow.com/questions/17960808
复制相似问题