两次加入两张桌子

时间:2016-04-05 04:36:20

标签: mysql sql

为篮球数据库编写查询,我们的游戏表有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;

帮助?

编辑:忘记提及,查询的目的是获得每个团队的获胜次数和损失次数。

1 个答案:

答案 0 :(得分:0)

COUNT聚合获取非NULL值的计数。这意味着它包含1和0。

在数值上下文中进行求值,相等比较返回1表示TRUE并返回0表示FALSE,如果任何一方(或双方)都为NULL,则只返回NULL。< / p>

要添加并忽略零,您可以改为使用SUM聚合。

由于winnerloser之间的交叉连接,查询的一个主要问题是可能会返回重复项。如果一个团队有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