SQL,努力相信拥有比加入更有效

SQL,努力相信拥有比加入更有效,sql,oracle,database,database-performance,query-performance,Sql,Oracle,Database,Database Performance,Query Performance,我试图在下表(**表示私钥)中找到为一支球队打过多场比赛的球员,很难相信我能提出的最好的查询(如下)是最有效的。关于如何改进它的想法,以及关于为什么会非常感谢的解释(尝试学习SQL) 你要问的是,哪些球员在一场以上的比赛中打过球 SELECT P.Player_Name FROM Player P GROUP BY P.Player_Name HAVING COUNT(DISTINCT P.GID) > 1 这将返回所有玩过1场以上游戏(GID)的玩家 如果您也想按团队分组,请执行以下操

我试图在下表(**表示私钥)中找到为一支球队打过多场比赛的球员,很难相信我能提出的最好的查询(如下)是最有效的。关于如何改进它的想法,以及关于为什么会非常感谢的解释(尝试学习SQL)


你要问的是,哪些球员在一场以上的比赛中打过球

SELECT P.Player_Name
FROM Player P
GROUP BY P.Player_Name
HAVING COUNT(DISTINCT P.GID) > 1
这将返回所有玩过1场以上游戏(GID)的玩家

如果您也想按团队分组,请执行以下操作:

SELECT P.Player_Name, T.Team_Name
FROM Player P
    JOIN Game G ON P.GID = G.GID
    JOIN Team T ON G.TID = T.TID
GROUP BY P.Player_Name, T.Team_Name
HAVING COUNT(DISTINCT G.GID) > 1
在玩家表中有GID似乎很奇怪。也许拥有一个PlayerGames表更有意义,因为它存储了PlayerId和GameId——更好地实现数据库规范化。播放器表应该只为每个播放器存储一条记录

另外,球员和球队之间的真正联系是什么。在这个场景中,你是说一个玩家必须玩一个游戏,一个游戏必须有一个团队(或者一个游戏应该有两个或更多的团队)。让我们知道你想要什么,我们可以帮助你提出最好的选择


祝您好运。

您能给我们一些示例数据和预期输出,以便更好地理解吗?另外,我认为桌子的设计有点错误
Player
只有
gid
name
<在
游戏中,code>gid
可以有两个队。因此,
player.gid
将保持不变,而球队在
game.tid
中可能会有所不同。如果播放器名称相同,则会出现更多问题。在播放器内部还有一个PID字段,还有一个MEMBEROF表。因为查询没有必要,所以我把它们删掉了。规范规定没有两个玩家会有相同的名字,我可能应该包括这一点。回头看,我可以看到潜在的混乱!这个想法是列出所有参加过两场比赛的球员以及他们所在的球队(因此,这包括任何转会等,他们必须打两场比赛,但不一定是同一支球队。谢谢,如果你看到我在回复Orangecrush的原始帖子上的评论,我意识到我应该解释得更清楚一点。查询分组正是我想要的(与我的一样)但不幸的是,它的效率似乎低于原始查询。这是真正的问题,我发现很难相信原始查询是最有效的,但我想不出更好的!我不确定我是否在跟踪您--这些查询是您最有效的…您的原始查询一团糟:)您有多个GROUP BY、多个表扫描等…可能最适合您使用示例(sqlfiddle.com)构建SQL FIDLE。更糟糕的情况是,使用我的第一个查询(无法获得比它更高效的查询)并在()中使用PlayerId。祝你好运。我正在通过aqua data studio在Oracle数据库上运行查询。执行计划显示,我发布的查询的节点成本为10,而你发布的查询为11。原始版本也使用了相当少的内存。这是我发布的第一个原因,我同意就我所知,您使用的联接方法(我之前也试过)应该更有效,但DBMS处理它的方式似乎不是这样的!
SELECT P.Player_Name, T.Team_Name
FROM Player P
    JOIN Game G ON P.GID = G.GID
    JOIN Team T ON G.TID = T.TID
GROUP BY P.Player_Name, T.Team_Name
HAVING COUNT(DISTINCT G.GID) > 1