【问题标题】:Joining 3 tables to count the score of a Match加入 3 个表来计算比赛的得分
【发布时间】:2015-08-11 20:01:15
【问题描述】:

我有 3 张桌子。

Team
  TeamId        Team 
   1       Manchester United
   2       Arsenal 
   3       Liverpool

Match    
 MatchId HomeTeamId AwayTeamId  MatchStartDate
 3         1           2          2/2/2015
 8         3           1          6/2/2015

Score
 ScoreId MatchId TeamId      ScorTime
 1         3      1      2/2/2015 12:30:00
 2         3      2      2/2/2015 12:35:00
 3         3      1      2/2/2015 12:38:00
 4         8      1      6/2/2015 12:45:00
 5         8      1      6/2/2015 12:49:00

我想要类似的东西

 MatchId HomeTeam            HomeTeamScore  AwayTeam     AwayTeamScore MatchDate
 3         Manchester United     2           Arsenal         1        2/2/2015
 8         Liverpool             0        Manchester United  2        6/2/2015

我已经尝试过了,但我没有得到正确的计数。

SELECT COUNT(hscore.MatchId) AS HomeScore
     , COUNT(ascore.MatchId) AS AwayScore 
FROM Match 
RIGHT OUTER JOIN Score AS hscore 
         ON Match.AwayTeamId = hscore.TeamId 
LEFT OUTER JOIN Score AS ascore 
         ON Match.HomeTeamId = ascore.TeamId

【问题讨论】:

  • 好吧,你没有告诉我们你的结果有什么问题,所以我来猜测一下。尝试使用count (distinct hscore.MatchId)
  • 你为什么使用右外连接和左外连接?他们不应该都留一个,因为如果匹配存在,您只关心分数。
  • 您的 hscore 别名(以及您的 HomeScore 结果)使用 AwayTeamId 是否是错字,反之亦然?或者这就是您问题的答案?

标签: sql-server database join


【解决方案1】:

这应该给你想要的

Select MatchID, H.Team as HomeTeam, HomeTeamScore = (Select Count(*) From Score Where MatchID = M.MatchID And TeamID = M.HomeTeamId), A.Team as AwayTeam, AwayTeamScore = (Select Count(*) From Score Where MatchID = M.MatchID And TeamID = M.AwayTeamId), MatchStartDate From Match M Inner Join Team H On M.HomeTeamId = H.TeamID Inner Join Team A On M.AwayTeamId = A.TeamID

【讨论】:

  • 我从不推荐使用相关子查询,它们会降低性能。
  • 是的,但它可以工作,如果需要,可以在以后对性能进行微调。
【解决方案2】:

试试

SELECT Match.Matchid
    , COUNT(hscore.MatchId) AS HomeScore
    , COUNT(ascore.MatchId) AS AwayScore 
FROM Match  
LEFT OUTER JOIN Score AS hscore 
         ON Match.HomeTeamId = hscore.TeamId AND Match.Matchid = hscore.Matchid
LEFT OUTER JOIN Score AS ascore 
         ON Match.AwayTeamId = ascore.TeamId AND Match.Matchid = ascore.Matchid
GROUP BY  Match.Matchid

如果您想添加团队名称,您还需要加入团队表两次,但这可以是内部连接。

【讨论】:

  • 我没有看到这个正确的分数,即使我认为它也有效.. Sql Fiddle sqlfiddle.com/#!3/2bc67/3
  • 我使用了你的加入,但没有注意到你加入了客队以获得主队,反之亦然。检查修订版本。
  • 左外连接不适用于这种情况,如果至少有一个数据,结果将是错误的。在这种情况下,MatchID 3 和 Awayteamscore 的计数是错误的。
【解决方案3】:

您可以使用 Cross Apply 像一个函数一样获取团队名称,然后只需选择您的分数..

SELECT  m.MatchId,
        ht.Team AS HomeTeam,
        (SELECT COUNT(*) 
         FROM Score s 
         WHERE s.MatchId = m.MatchId AND s.TeamId = ht.TeamId) AS HomeTeamScore,
        at.Team AS AwayTeam,
        (SELECT COUNT(*) 
         FROM Score s 
         WHERE s.MatchId = m.MatchId AND s.TeamId = at.TeamId) AS AwayTeamScore,
        m.MatchStartDate
FROM    Match m
        CROSS APPLY (SELECT TeamID, Team FROM Team WHERE TeamId = m.HomeTeamId) ht
        CROSS APPLY (SELECT TeamID, Team FROM Team WHERE TeamId = m.AwayTeamId) at

SQL Fiddle

【讨论】:

    【解决方案4】:
    SELECT
         m.MatchID
        ,ht.Team HomeTeam
        ,htscore.score HomeTeamScore
        ,at.Team AwayTeam
        ,atscore.score AwayTeamScore
        ,m.MatchStartDate MatchDate
    FROM Match m
    INNER JOIN Team ht ON m.HomeTeamID=ht.TeamID
    INNER JOIN Team at ON m.AwayTeamID=at.TeamID
    INNER JOIN (
        SELECT MatchID,TeamID,COUNT(*) score
        FROM Score
        GROUP BY MatchID,TeamID
    ) htscore ON htscore.MatchID=m.MatchID AND htscore.TeamID=ht.TeamID
    INNER JOIN (
        SELECT MatchID,TeamID,COUNT(*) score
        FROM Score
        GROUP BY MatchID,TeamID
    ) atscore ON atscore.MatchID=m.MatchID AND atscore.TeamID=at.TeamID
    

    【讨论】:

      【解决方案5】:

      这是我的版本:

      WITH Scores (MatchId, TeamId, cnt) AS (
        SELECT MatchId, TeamId, COUNT(*)
        FROM Score
        GROUP BY MatchId, TeamId
      )
      SELECT Match.Matchid,
             COALESCE(h.cnt, 0) AS HomeScore,
             COALESCE(a.cnt, 0) AS AwayScore 
      FROM Match  
      LEFT OUTER JOIN Scores h ON Match.MatchId = h.MatchId AND Match.HomeTeamId = h.TeamId
      LEFT OUTER JOIN Scores a ON Match.MatchId = a.MatchId AND Match.AwayTeamId = a.TeamId
      

      SQL Fiddle

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多