为篮球数据库编写查询,我们的游戏表有winsID和loserID,每个都是teamID。尝试了以下两个查询,每个查询都正确地给了我胜利的数量,但给了我相同数量的损失。
SELECT team.name as Team_Name, COUNT(team.teamID=winner.winnerID) as Wins, COUNT(team.teamID=loser.loserID) as Losses
FROM team join games winner on winner.winnerID=team.teamID join games loser on loser.loserID=team.teamID
GROUP BY team.name
ORDER BY Wins, Team_Name;
SELECT team.name as Team_Name, COUNT(team.teamID=games.winnerID) as Wins, COUNT(team.teamID=games.loserID) as Losses
FROM (team INNER JOIN games on games.winnerID=team.teamID)
GROUP BY team.name
ORDER BY Wins, team.name;
帮助?
编辑:忘记提及,查询的目的是获得每个团队的获胜次数和损失次数。
答案 0 :(得分:0)
COUNT
聚合获取非NULL值的计数。这意味着它包含1和0。
在数值上下文中进行求值,相等比较返回1
表示TRUE并返回0
表示FALSE,如果任何一方(或双方)都为NULL,则只返回NULL
。< / p>
要添加并忽略零,您可以改为使用SUM
聚合。
由于winner
和loser
之间的交叉连接,查询的一个主要问题是可能会返回重复项。如果一个团队有5胜4负,那么查询将生成一个20(= 5 x 4)行的中间集。
要获得胜负的数量,我们需要一个游戏的唯一标识符(例如,游戏表中的游戏关键字作为PRIMARY KEY。)有了这个,我们可以得到一个计数游戏币的不同值。例如:
COUNT(DISTINCT IF(winner.winnerid=team.teamid,winner.gameid,NULL)) AS wins
有几种查询模式可以获得每个团队的获胜次数和损失次数。
以下是一个例子:
SELECT t.name AS team_name
, COUNT(IF(t.teamid=g.winnerid,1,NULL) AS wins
, COUNT(IF(t.teamid=g.loserid ,1,NULL) AS losses
FROM team
LEFT
JOIN games g
ON ( g.winnerid = t.teamid OR g.loserid = t.teamid )
GROUP
BY t.name
ORDER
BY wins DESC
, t.name
有了这个,我们只加入游戏桌一次,所以我们不会得到一个交叉产品。另请注意,如果teamid 不等于winnerid,我们返回NULL而不是0.因此COUNT将仅包括获胜者,而不是所有行。
我们使用外部联接(而不是内部联接),以防团队的游戏中没有相关的行。这允许我们返回一个计数为零的团队。
我们可以使用SUM聚合而不是COUNT,例如:
SELECT t.name AS team_name
, IFNULL(SUM(t.teamid=g.winnerid),0) AS wins
, IFNULL(SUM(t.teamid=g.loserid) ,0) AS losses
FROM team
LEFT
JOIN games g
ON ( g.winnerid = t.teamid OR g.loserid = t.teamid )
GROUP
BY t.name
ORDER
BY wins DESC
, t.name
使用SUM(),我们有可能返回NULL值。为了将那些转换为零,我们使用IFNULL函数。
还有其他几种查询模式可以获得相同的结果......例如而不是使用连接,使用SELECT列表中的相关子查询...
SELECT t.name
, ( SELECT COUNT(1)
FROM game w
WHERE w.winner_id = t.teamid
) AS wins
, ( SELECT COUNT(1)
FROM game l
WHERE l.loserid = t.teamid
) AS losses
FROM team t
ORDER BY wins DESC
, t.name