如果值大于SQL中的上一个,请选择记录

时间:2018-05-16 04:10:26

标签: sql sql-server common-table-expression sql-server-2017

我有这个T-SQL查询

WITH CTE AS 
(
    SELECT  
        m.Season AS 'Season',
        SUM(bi.Runs) AS 'Runs',
        p.LastName + ' ' + SUBSTRING(p.FirstName, 1, 1) AS 'PlayerName' 
    FROM Player p
    JOIN BatInnings bi on bi.fk_Player_Id = p.id  
    JOIN Innings i on i.Id = bi.fk_Innings_Id
    JOIN Team t on t.id = i.fk_Team_Id
    JOIN Match m on m.id = i.fk_Match_Id
    WHERE   
        (p.id = @playerId OR @playerId IS NULL) 
        AND m.MatchType IN (@matchType1, @matchType2, @matchType3) 
        AND (i.fk_Team_Id = @teamId OR @teamId IS NULL) 
        AND (t.fk_Club_Id = @clubId OR @clubId IS NULL)
    GROUP BY 
        m.season, p.LastName + ' ' + SUBSTRING(p.FirstName, 1, 1)
) 
SELECT CTE.* 
FROM CTE 
WHERE CTE.Runs = (SELECT MAX(CTE2.Runs) 
                  FROM CTE CTE2 
                  WHERE CTE2.Season = CTE.Season) 
ORDER BY CTE.Season

根据每个赛季最高得分手数列出一个名单。结果将如下所示。

Season   Runs   Player
1990/91  689    Todd D
1991/92  617    Grantham N
1992/93  838    Todd D
1993/94  532    Todd D
1994/95  628    Todd D
1995/96  584    Downer M
1996/97  743    Todd D
1997/98  742    Brown S
1998/99  841    Todd D
1999/00  902    Hart M

我想进一步提高此查询,然后拉出每条记录高于之前选择的记录。因此,使用前面的列表,此查询的结果将类似于

Season   Runs   Player
1990/91  689    Todd D
1992/93  838    Todd D
1998/99  841    Todd D
1999/00  902    Hart M

如果需要,很高兴提供更多信息。

由于

3 个答案:

答案 0 :(得分:1)

试试这个:

;with cte
AS
(
 SELECT '1990/91' AS Season, 689 AS Runs, 'Todd D' AS Player
  Union All
 SELECT '1991/92' AS Season, 617 AS Runs, 'Grantham N' AS Player
  Union All
 SELECT '1992/93' AS Season, 838 AS Runs, 'Todd D' AS Player
  Union All
 SELECT '1993/94' AS Season, 532 AS Runs, 'Todd D' AS Player
  Union All
 SELECT '1994/95' AS Season, 628 AS Runs, 'Todd D' AS Player
  Union All
 SELECT '1995/96' AS Season, 584 AS Runs, 'Downer M' AS Player
  Union All
 SELECT '1996/97' AS Season, 743 AS Runs, 'Todd D' AS Player
 Union All
 SELECT '1997/98' AS Season, 742 AS Runs, 'Brown S' AS Player
  Union All
 SELECT '1998/99' AS Season, 841 AS Runs, 'Todd D' AS Player
 Union All
SELECT '1999/00' AS Season, 902 AS Runs, 'Hart M' AS Player
 )

,cte2
AS
(
  SELECT *,
  MAX(Runs) OVER(Order By (Select NULL) ROWS BETWEEN UNBOUNDED PRECEDING AND 
  CURRENT ROW) As PreMax
  FROM cte
)

 Select Season,Runs,Player from Cte2
 Where Runs>=PreMax

SQL小提琴:http://sqlfiddle.com/#!18/c6e8e/9

答案 1 :(得分:0)

您可以使用窗口函数MAX() OVER ()获得最大值,直到该季节进行比较:

WITH CTE AS (
    SELECT  m.Season AS 'Season',
        SUM(bi.Runs) AS 'Runs',
        p.LastName + ' ' + SUBSTRING(p.FirstName, 1, 1) AS 'PlayerName' 
    FROM Player p
    JOIN BatInnings bi on bi.fk_Player_Id = p.id  
    JOIN Innings i on i.Id = bi.fk_Innings_Id
    JOIN Team t on t.id = i.fk_Team_Id
    JOIN Match m on m.id = i.fk_Match_Id
    WHERE (p.id = @playerId OR @playerId IS NULL) 
        AND m.MatchType IN (@matchType1, @matchType2, @matchType3) 
        AND (i.fk_Team_Id = @teamId OR @teamId IS NULL) 
        AND (t.fk_Club_Id = @clubId OR @clubId IS NULL)
    GROUP BY m.season, p.LastName + ' ' + SUBSTRING(p.FirstName, 1, 1)
) 
, cte1 AS 
(
    SELECT *
    FROM CTE c
    WHERE Runs = (
        SELECT MAX(Runs) 
        FROM CTE 
        WHERE Season = c.Season
    ) 
)
, cte2 AS 
(
    SELECT season, COALESCE(MAX(runs) OVER (ORDER BY season), 0) AS max_runs_to_season
    FROM cte1 
)
SELECT *
FROM cte1 c
WHERE runs >= (
    SELECT max_runs_to_season
    FROM cte2 
    WHERE season = c.season
)
ORDER BY season;

答案 2 :(得分:0)

我不熟悉SQL中的窗口函数,所以我的答案只使用CTE和子查询。

我将您的主要查询放在一个名为[SeasonResults]的新CTE中,并从那里扩展了查询。

一个名为[MaxSeasonResults]的新CTE确定了每个赛季的最佳成绩。

WITH
    [CTE] AS
    (
        SELECT  
            m.Season AS 'Season',
            SUM(bi.Runs) AS 'Runs',
            p.LastName + ' ' + SUBSTRING(p.FirstName, 1, 1) AS 'PlayerName' 
        FROM Player p
        JOIN BatInnings bi on bi.fk_Player_Id = p.id  
        JOIN Innings i on i.Id = bi.fk_Innings_Id
        JOIN Team t on t.id = i.fk_Team_Id
        JOIN Match m on m.id = i.fk_Match_Id
        WHERE   
            (p.id = @playerId OR @playerId IS NULL) 
            AND m.MatchType IN (@matchType1, @matchType2, @matchType3) 
            AND (i.fk_Team_Id = @teamId OR @teamId IS NULL) 
            AND (t.fk_Club_Id = @clubId OR @clubId IS NULL)
        GROUP BY 
            m.season, p.LastName + ' ' + SUBSTRING(p.FirstName, 1, 1)
    ),
    [SeasonResults] AS
    (
        SELECT CTE.* 
        FROM CTE 
        WHERE CTE.Runs = (SELECT MAX(CTE2.Runs) 
                          FROM CTE CTE2 
                          WHERE CTE2.Season = CTE.Season) 
        ORDER BY CTE.Season
    ),
    [MaxSeasonResults] AS
    (
        SELECT
            [Season],
            [MaxRuns] = MAX([Runs])
        FROM [SeasonResults]
        GROUP BY [Season]
    )
SELECT R.*
FROM
    [SeasonResults] AS R
    JOIN [MaxSeasonResults] AS M ON
        M.[Season] = R.[Season]
        AND M.[MaxRuns] = R.[Runs]
WHERE
    M.[MaxRuns] > (SELECT COALESCE(MAX(_M.[MaxRuns]), 0)
                   FROM [MaxSeasonResults] AS _M
                   WHERE _M.[Season] < M.[Season])
ORDER BY R.[Season];

也许可以进行更多优化/重构,但我必须使用包含给定结果集的临时表来测试我的查询,因此我很难检查并测试任何进一步的优化。对不起。