我正在尝试从游戏桌中获取数据以及所有玩家是否已注册可用的匹配(是/否) 可用匹配是日期为当前或未来的匹配
玩家
(PK)Gamer_Id
Gamer_firstName,
Gamer_lastName,
Gamer experience(Y/N)
Game_matches
(PK)FK GamerId,
(PK)FK MatchId,
Gamer_score
匹配
(PK)Match_Id,
gameDate,
ExperiencedGamers_needed,
InExperiencedGamers_needed
这是我尝试过的,我知道它不完整。 我是否也需要使用CASE?
SELECT G.*, COUNT(M.`matchId`)
FROM game_matches GM
LEFT JOIN MATCHES M
ON M.`matchId` = GM.`matchId`
LEFT JOIN Gamers G ON G.`userId` = GM.`userId`
WHERE G.`gameDate` >= DATE(NOW())
GROUP BY G.`userId`
除了使用JW的交叉连接解决方案之外,还有其他方法可以实现此目的吗?
答案 0 :(得分:3)
SELECT a.GamerID,
a.Name,
COUNT(*) = COUNT(c.GamerID)
FROM Gamers a
CROSS JOIN `Match` b
LEFT JOIN GameMatches c
ON a.GamerID = c.GamerID AND
b.MatchID = c.MatchID
WHERE b.gameDate >= CURDATE()
GROUP BY a.GamerID,
a.Name
查询的作用是首先获得所有游戏玩家的笛卡尔积和今天开始的所有比赛。之后,结果将在表GameMatches
的两列上加入:GamerID
和MatchID
。
如果表的笛卡尔积的结果在表GameMatches
上没有匹配,则列的值为 NULL 。因此,它测试COUNT(*)
,即记录总数是否等于COUNT(c.GamerID)
,这只是已注册的游戏玩家总数。
答案 1 :(得分:0)
您只选择将来会有比赛的游戏。如果您想要未来匹配的计数,则需要条件聚合:
SELECT G.*, sum(case when g.gameDate >= date(now()) then 1 else 0 end) as FutureMatches
FROM game_matches GM
LEFT JOIN MATCHES M
ON M.`matchId` = GM.`matchId`
LEFT JOIN Gamers G ON G.`userId` = GM.`userId`
GROUP BY G.`userId`
在实践中,您可以使用inner join
而不是left join
,因为ID应该在表之间匹配(除非您对完全没有匹配的用户感兴趣)。
答案 2 :(得分:0)
WITH MATCHES AS
(
SELECT COUNT(*) AS TOTAL_MATCHES FROM MATCH WHERE gameDate >= CURR_DATE
)
GM AS
(SELECT G.GAMER_ID, COUNT(*) AS GAMER_MATCHES
GAMERS G, GAME_MATCHES GM
WHERE G.GAMER_ID = GM.GAMER_ID
GROUP BY G.GAMER_ID
)
SELECT GM.GAMER_ID
FROM GM, MATCH
WHERE GAMER_MATCHES = TOTAL_MATCHES