用于体育统计的TSQL查询无法做到这一点

时间:2016-03-19 11:55:40

标签: sql tsql

似乎是一个简单的查询,但我无法做到,请帮忙。他们给了我一些限制:不要使用多个子查询和临时表,但CTE和外部应用。

And this is the desired result
表格是:游戏,团队和玩家。

This is the DB Schema

我无法过滤每支球队最有价值球员的情况,因为对于球队1来说,它有: 玩家1获得MVP 2倍, 玩家2赢了5次 球员3赢得1次MVP

我看到了所有这些,我只需要看到玩家2是他们中最赢家的。

这是我到目前为止所做的查询:

SELECT
       q.Name,  
       q.Stadium,
       q.Logo,
       COUNT(q.Played) as Played,
       SUM(q.PlayedAtHome) as [Played Home], 
       SUM(q.PlayedAway)  as [Played Away],
       SUM(q.Won) as Won,
       SUM(q.Lost) as Lost,
       MAX(q.BigestWon) as BigestWon,
       q.MVP,
       Max(mvpXtimes) mvcXtimes
FROM
(
SELECT homeTeam.Name,  
       homeTeam.Stadium,
       homeTeam.Logo,
       1 as Played,
       1 as PlayedAtHome,
       0 as PlayedAway,
       mvp.Name as MVP,
       COUNT(mvp.Name) as mvpXtimes,
       CASE
          WHEN (g.HomeScore > g.AwayScore) THEN 1
          ELSE 0
       END as Won,
       CASE
          WHEN (g.HomeScore < g.AwayScore) THEN 1
          ELSE 0
       END as Lost,
       CASE
          WHEN (g.HomeScore > g.AwayScore) THEN g.HomeScore
          ELSE 0
       END as BigestWon,
       CASE
          WHEN (g.HomeScore < g.AwayScore) THEN g.HomeScore
          ELSE 0
       END as LostScoreLoser
FROM  dbo.Games as g
      -- Home team
      INNER JOIN dbo.Teams homeTeam 
         ON g.HomeTeamID = homeTeam.TeamID 
      -- Mvp of the game
      INNER JOIN dbo.Players as mvp 
         ON g.MVPPlayerID = mvp.PlayerID
WHERE g.HomeTeamID = 8
group by homeTeam.Name,  
       homeTeam.Stadium,
       homeTeam.Logo,
       mvp.Name,
       CASE
          WHEN (g.HomeScore > g.AwayScore) THEN 1
          ELSE 0
       END,
       CASE
          WHEN (g.HomeScore < g.AwayScore) THEN 1
          ELSE 0
       END,
       CASE
          WHEN (g.HomeScore > g.AwayScore) THEN g.HomeScore
          ELSE 0
       END,
       CASE
          WHEN (g.HomeScore < g.AwayScore) THEN g.HomeScore
          ELSE 0
       END  
UNION ALL

SELECT awayTeam.Name,  
       awayTeam.Stadium,
       awayTeam.Logo,
       1 as Played,
       0 as PlayedAtHome,
       1 as PlayedAway,
       mvp.Name as MVP,
       COUNT(mvp.Name) as mvpXtimes,
       CASE
          WHEN (g.AwayScore > g.HomeScore ) THEN 1
          ELSE 0
       END as Won,
       CASE
          WHEN (g.AwayScore < g.HomeScore ) THEN 1
          ELSE 0
       END as Lost,
       CASE
          WHEN (g.AwayScore > g.HomeScore ) THEN g.AwayScore
          ELSE 0
       END as BigestWon,
        CASE
          WHEN (g.AwayScore < g.HomeScore ) THEN g.AwayScore
          ELSE 0
       END as LostScoreLoser
FROM  dbo.Games as g
      -- Away team
      INNER JOIN dbo.Teams awayTeam
        ON g.AwayTeamID = awayTeam.TeamID 
      -- Mvp of the game
      INNER JOIN dbo.Players as mvp 
         ON g.MVPPlayerID = mvp.PlayerID
WHERE g.AwayTeamID = 8 
group by awayTeam.Name,  
       awayTeam.Stadium,
       awayTeam.Logo,
       mvp.Name,
       CASE
          WHEN (g.AwayScore > g.HomeScore ) THEN 1
          ELSE 0
       END,
       CASE
          WHEN (g.AwayScore < g.HomeScore ) THEN 1
          ELSE 0
       END,
       CASE
          WHEN (g.AwayScore > g.HomeScore ) THEN g.AwayScore
          ELSE 0
       END,
        CASE
          WHEN (g.AwayScore < g.HomeScore ) THEN g.AwayScore
          ELSE 0
       END
 ) as q
 GROUP BY    q.Name,  
     q.Stadium,
     q.Logo ,
     q.MVP

1 个答案:

答案 0 :(得分:0)

我是通过miselft做到的,不确定是否有效但是有效:

WITH 
cteGames (TeamID, GameDateTime, Played, PlayedHome, PlayedAway, Won, Lost,    BigestWon, BigestLost)
AS
  (     
    SELECT
        q.TeamID,
        MAX(q.GameDateTime) as GameDateTime,
        COUNT(q.Played) as Played,
        SUM(q.PlayedHome) as PlayedHome, 
        SUM(q.PlayedAway)  as PlayedAway,
        SUM(q.Won) as Won,
        SUM(q.Lost) as Lost,
        MAX(q.BigestWon) as BigestWon,
        MAX(q.BigestLost) as BigestLost
    FROM
    (
         -- Home team
         SELECT    
                   g.HomeTeamID as TeamID,
                   g.GameDateTime,
                   1 as Played,
                   1 as PlayedHome,
                   0 as PlayedAway,
                   CASE
                      WHEN (g.HomeScore > g.AwayScore) THEN 1
                      ELSE 0
                   END as Won,
                   CASE
                      WHEN (g.HomeScore < g.AwayScore) THEN 1
                      ELSE 0
                   END as Lost,
                   CASE
                      WHEN (g.HomeScore > g.AwayScore) THEN g.HomeScore - g.AwayScore
                      ELSE 0
                   END as BigestWon,
                   CASE
                      WHEN (g.HomeScore < g.AwayScore) THEN g.AwayScore - g.HomeScore
                      ELSE 0
                   END as BigestLost
        FROM  dbo.Games as g
              INNER JOIN dbo.Teams homeTeam 
                 ON g.HomeTeamID = homeTeam.TeamID 

        UNION ALL

        -- Away team
        SELECT 
               g.AwayTeamID as TeamID,
               g.GameDateTime,
               1 as Played,
               0 as PlayedHome,
               1 as PlayedAway,
               CASE
                  WHEN (g.AwayScore > g.HomeScore ) THEN 1
                  ELSE 0
               END as Won,
               CASE
                  WHEN (g.AwayScore < g.HomeScore ) THEN 1
                  ELSE 0
               END as Lost,
               CASE
                  WHEN (g.AwayScore > g.HomeScore ) THEN g.AwayScore - g.HomeScore
                  ELSE 0
               END as BigestWon,
                CASE
                  WHEN (g.AwayScore < g.HomeScore ) THEN g.HomeScore - g.AwayScore 
                  ELSE 0
               END as BigestLost
        FROM  dbo.Games as g
              INNER JOIN dbo.Teams awayTeam
                ON g.AwayTeamID = awayTeam.TeamID 
     ) q
  GROUP BY  q.TeamID

)

SELECT t.Name, t.Stadium, t.Logo, cte.Played,  cte.PlayedHome,                 cte.PlayedAway, cte.Won, cte.Lost, bw.Score as  BigestWon, bl.Score as BigestLost, cte.GameDateTime, a.Name as MVP
FROM dbo.Teams as t
   INNER JOIN cteGames cte
     ON t.TeamID = cte.TeamID
CROSS APPLY
(
  -- MVP part
  SELECT  TOP 1
        p.Name
  FROM games as g
       INNER JOIN dbo.Players as p
         ON g.MVPPlayerID = p.PlayerID
       INNER JOIN dbo.Team_Player as tp
         ON p.PlayerID = tp.PlayerID
  WHERE tp.TeamID = t.TeamID
  GROUP BY p.Name
  ORDER BY COUNT(g.MVPPlayerID) DESC
) a
CROSS APPLY
dbo.fn_GetBigestWin (T.TeamID) as bw
CROSS APPLY
dbo.fn_GetBigestLost(T.TeamID) as bl


ALTER FUNCTION [dbo].[fn_GetBigestWin]
(
  @teamId INT
)  
RETURNS TABLE 
AS 
RETURN 
( 
 SELECT
       TOP 1 
       a.GameID,
       a.Score
 FROM
         (
              SELECT 
                    g.GameID,
                    g.HomeScore - g.AwayScore as  ScoreDifference,
                    RTRIM(LTRIM(STR(g.HomeScore))) + '-' + RTRIM(LTRIM(STR(g.AwayScore))) as Score
              FROM games as g
              WHERE g.HomeTeamID = @teamId
                    and g.HomeScore > g.AwayScore

              UNION ALL

              SELECT  
                    g.GameID,
                    g.AwayScore - g.HomeScore as  ScoreDifference,
                    RTRIM(LTRIM(STR(g.AwayScore))) + '-' +  RTRIM(LTRIM(STR(g.HomeScore)))  as Score
              FROM games as g
              WHERE g.AwayTeamID = @teamId
                    and  g.AwayScore > g.HomeScore 
         ) a
 GROUP BY a.GameID,
          a.Score
 ORDER BY MAX(a.ScoreDifference) DESC
) 


ALTER FUNCTION [dbo].[fn_GetBigestLost]
(
  @teamId INT
)  
RETURNS TABLE 
AS 
RETURN 
   ( 
     SELECT
           TOP 1 
           a.GameID,
           a.Score
     FROM
             (
                  SELECT 
                        g.GameID,
                        g.AwayScore - g.HomeScore  as ScoreDifference,
                        RTRIM(LTRIM(STR(g.HomeScore))) + '-' + RTRIM(LTRIM(STR(g.AwayScore))) as Score
                  FROM games as g
                  WHERE g.HomeTeamID = @teamId
                        and g.HomeScore < g.AwayScore

                  UNION ALL

                  SELECT  
                        g.GameID,
                        g.HomeScore - g.AwayScore as ScoreDifference,
                        RTRIM(LTRIM(STR(g.AwayScore))) + '-' +  RTRIM(LTRIM(STR(g.HomeScore)))  as Score
                  FROM games as g
                  WHERE g.AwayTeamID = @teamId
                        and  g.AwayScore < g.HomeScore 
             ) a
     GROUP BY a.GameID,
              a.Score
     ORDER BY MAX(a.ScoreDifference) DESC
   )