-1

我正在尝试从游戏表中获取数据以及是否所有玩家都已注册可用的比赛(是/否)可用的比赛是日期是当前或将来的比赛

游戏玩家

(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 的交叉连接解决方​​案之外,还有其他方法可以实现这一目标吗?

4

3 回答 3

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在两列的表上连接:GamerIDMatchID

如果表的笛卡尔积的结果在 table 上没有匹配GameMatches项,则列的值为NULL。因此,它测试COUNT(*)哪个是记录的总数是否等于COUNT(c.GamerID)哪个只是已注册的游戏玩家总数。

于 2013-04-03T03:00:47.977 回答
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 应该匹配(除非您对根本没有匹配的用户感兴趣)。

于 2013-04-03T02:51:41.080 回答
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
于 2013-04-03T04:48:47.640 回答