mysql 查询 - 使用左连接和 where 子句的多个计数
Posted
技术标签:
【中文标题】mysql 查询 - 使用左连接和 where 子句的多个计数【英文标题】:mysql query - multiple counts using left join and where clause 【发布时间】:2013-09-11 13:20:31 【问题描述】:我目前正在尝试获取以下数据:
用户名、UserImageURL、已玩游戏总数、已完成游戏、输掉游戏、平均获胜(百分比)和用户积分
还有另一组数据:
用户统计数据,例如:
联赛中玩的游戏最多:23 - Monster Killers 赢得最多的游戏:19/23 - Monster Killers 失利最多的游戏:3/32 - Frog Racers 您的游戏获胜准确度(所有游戏的总和)- 68% 准确度网站统计:
联赛中玩的游戏最多:650 - Helicopter Run 热门游戏:1200 - Monster Killers 全站胜率:82%我有以下表格:
-用户表-
userID (int-pk), userName (varchar), userImageUrl (text)
-游戏桌-
gameId (int-pk), gameName (varchar), gameUserID (int), gameLeagueId (int), score1 (int), score2 (int), gameResultOut (0 or 1), gameWon (0 or 1)
-用户平衡表-
ubId(int-pk) userId (int) balance (int)
-联赛表- 联赛ID (int-pk) 联赛名称 (varchar)
只是为了让您提前了解正在发生的事情,当用户玩游戏并选择一些结果时,会在游戏表中插入一行。由于游戏是基于时间的,所以当结果出来时,会检查是否有任何游戏具有该 ID,并将根据用户选择的内容将 gameResultOut 更新为 1 并将 gameWon 更新为 1 或 0得分。
我尝试了以下方法:
SELECT u.userID, u.userName, u.userImageUrl, l.leagueName ,
COUNT(g.gameId) AS predTotal,
(SELECT COUNT(g.gameId) FROM games AS g WHERE g.gameResultOut = 1 AND g.gameWon = 1) AS gamesWon,
(SELECT COUNT(g.gameId) FROM games AS g WHERE g.gameResultOut = 1 AND g.gameWon = 0) AS gamesLost,
ub.balance
FROM games AS g
LEFT JOIN league AS l ON l.leagueId = g.gameLeagueId
LEFT JOIN user AS u ON u.user_id = g.gameUserID
LEFT JOIN user_balance AS ub ON ub.userId = u.userID
WHERE l.leagueId = 4
GROUP BY u.userId
ORDER BY ub.balance DESC
查询后我可以很容易地计算出胜率,所以这不是问题,但是胜负的结果都是一样的,即使改变了 leageId,结果仍然是一样的,这不是我想要什么。
谁能帮忙?
感谢和问候, 死灵
【问题讨论】:
【参考方案1】:据我所知,games 表存储了用户 玩过的游戏。因此,为了了解每个用户玩过/赢过/输了多少游戏,您缺少 games 和 users之间的子查询中的链接>.
您的子查询是:
(SELECT COUNT(g.gameId ) FROM games AS g WHERE g.gameResultOut = 1 AND g.gameWon = 1) AS gamesWon,
(SELECT COUNT(g.gameId) FROM games AS g WHERE g.gameResultOut = 1 AND g.gameWon = 0) AS gamesLost,
他们应该是:
(SELECT COUNT(gw.gameId ) FROM games AS gw WHERE gw.gameResultOut = 1 AND gw.gameWon = 1 AND gw.gameUserID = u.user_id) AS gamesWon,
(SELECT COUNT(gl.gameId) FROM games AS gl WHERE gl.gameResultOut = 1 AND gl.gameWon = 0 AND gl.gameUserID = u.user_id) AS gamesLost,
我猜这就是你要找的:)
EDIT 基于 cmets,为用户和站点统计添加提示:
对于这些信息,您需要执行几个不同的查询,因为它们中的大多数将按给定列汇总一些值和/或分组,这不适合另一个查询。我会尝试给你一些想法,以便你可以研究它们。
用户统计
大多数游戏的赢或输
您提供的查询的上一个答案计算了用户输/赢任何场比赛的次次数,但不区分比赛之间的此数据。
所以,如果你想知道在哪个游戏用户中的赢/输最多,你应该有这样的东西:
SELECT
g.gameName,
-- How many times the user won per game
(SELECT COUNT(gw.gameId) FROM games gw WHERE gw.gameResultOut = 1 AND gw.gameWon = 1 AND gw.gameUserID = u.user_id) AS gamesWon,
-- How many times the user payed each game
COUNT(g.gameId) AS gamesPlayed,
-- The Win Ratio. This may need a little work on, depending on what you want.
-- Be aware that if a user played a game 1 time and won, it's ratio will be 1 (100%)
-- So maybe you'll want to add your own rule to determine which game should show up here
(gamesWon / gamesPlayed) AS winRatio
FROM
games g
INNER JOIN user u ON u.user_id = g.gameUserID
-- Groups and counts data based on games + users
GROUP BY g.gameId, u.user_id
-- Now you order by the win ratio
ORDER BY winRatio DESC
-- And get only the first result, which means the game the player has most wins.
LIMIT 1
对于输掉的比赛,它几乎是相同的查询,只是更改所需的字段和数学。
比赛获胜的准确性
有点像前面的查询,除了你不再按游戏ID 分组。只需按用户分组并计算一下即可。
网站统计
嗯,据我所知,我们仍在进行类似的查询。不同之处在于,对于整个站点统计信息,您永远不会按用户分组。您可以按游戏或联赛分组,具体取决于您要达到的目标。
底线:看起来大多数查询都是相似的,您必须使用它们并适应您需要检索的每个信息。 请注意,它们可能无法正常工作,因为我无法在您的数据库上测试它们。您可能需要根据您的数据库/表架构更正一些不一致的地方。
我希望这可以让您对工作有所了解。
【讨论】:
谢谢你的朋友,但它并没有完美地工作,我不知道为什么它得到相同的结果输掉/赢得的游戏数量和失去的游戏数量虽然其他用户现在有不同的值: )。获取上述用户和站点统计信息的最佳方法是什么?如何制定一个或两个查询?我还在学习mysql。感谢您的帮助! 好吧,我想您需要进行几个不同的查询才能获得所有这些信息。看:根据我的回答,您可能知道用户在所有游戏中赢得了多少游戏,但您无法确定它在哪个特定游戏中获胜次数最多。所以这意味着这是另一个查询。我将尝试编辑我的答案并添加一些示例来向您展示路径;) 非常感谢您的帮助。关于第一个查询,非常感谢。了解到当我需要获取唯一数据时我必须更改子查询 AS gw 并且我仍然必须添加用户和游戏的关系。我将测试其他查询并让您知道。当一切正常时会回答正确的问题:) 谢谢您的帮助 不知道为什么要问未知栏gamesWon。不是选择AS栏吗?不知道为什么要问未知栏gamesWon。不是选择AS列吗? 可能是因为子查询中有错字,我使用的是g.gameWon
而不是gw.gameWon
(我已经编辑并修复了查询)。如果这不是问题,请发布您的整个查询,以便我查看。以上是关于mysql 查询 - 使用左连接和 where 子句的多个计数的主要内容,如果未能解决你的问题,请参考以下文章