【问题标题】:SQL Query: last, second last, third last..value (Microsoft SQL)SQL 查询:最后一个、倒数第二个、倒数第三个..值 (Microsoft SQL)
【发布时间】:2012-10-31 14:23:03
【问题描述】:

我正在尝试为运动队构建报告。结果存储在 SQL 数据库中,如下所示:

对于报告,我需要在 Home2-Away4 列中填充相应的结果。 这意味着:

想象一下:ID=10 和 Home(no.) (Team#) = 1 --> Home1 = 结果 一场 比赛之前 ID=3 和球队客场比赛,结果为 0 (=home1)。这是我已经做过的,但是 Home2 = 结果 场比赛前,因为 Home3=result 三场 场比赛以前等等。

我是这样做的:

SELECT top 1 [result_home] from (SELECT Top 2 [result_home] FROM 
(SELECT top 2 [result_home]  from [Table]
where [ID] < 10  and ( [Home(no.)]=1 or [Away(No.)]=1 ) order by [ID] desc  ) top2     )top1 

(Microsoft SQL Server Express 2012 顺便说一句。)

我编写了一个小的 Java 代码,它决定是从 result_home 还是 result_away 中进行选择。

基本问题是:如何查询两天前的比赛结果?

提前致谢。

亲切的问候

斯蒂芬

【问题讨论】:

    标签: sql sql-server-2012-express


    【解决方案1】:

    我认为您需要LAG 函数。最简单的情况是这样的:

    [Home1] = LAG(result_Home, 1) OVER(PARTITION BY [Home(no.)] ORDER BY ID),
    

    但是,它并不像这样简单,因为您需要引用 home 或 away,因此您需要首先取消透视数据

    SELECT  ID,
            Type,
            TeamID,
            Result
    FROM    T
            CROSS APPLY 
            (   VALUES 
                    ('Home', [Home(no.)], Result_Home), 
                    ('Away', [Away(no.)], Result_Away)
            ) Upvt (Type, TeamID, Result);
    

    这意味着您可以在一列中访问每个团队的结果,无论是主场还是客场(对于滞后功能)。

    然后使用这些未透视的数据,您应用滞后来获得前 4 个结果(我使用了 ORDER BY ID,但我假设我缺少一个日期字段?):

    SELECT  *,
            [Result1] = LAG(Result, 1) OVER(PARTITION BY TeamID ORDER BY ID),
            [Result2] = LAG(Result, 2) OVER(PARTITION BY TeamID ORDER BY ID),
            [Result3] = LAG(Result, 3) OVER(PARTITION BY TeamID ORDER BY ID),
            [Result4] = LAG(Result, 4) OVER(PARTITION BY TeamID ORDER BY ID)
    FROM    (Previous Query)
    

    然后,一旦您获得了每支球队每场比赛的前 4 个结果,您就可以将未透视的数据重新组合在一起,以使主队和客队再次位于同一行,从而提供完整的查询:

    WITH Results AS
    (   SELECT  ID,
                Type,
                TeamID,
                Result
        FROM    T
                CROSS APPLY 
                (   VALUES 
                        ('Home', [Home(no.)], Result_Home), 
                        ('Away', [Away(no.)], Result_Away)
                ) Upvt (Type, TeamID, Result)
    ), Results2 AS
    (   SELECT  *,
                [Result1] = LAG(Result, 1) OVER(PARTITION BY TeamID ORDER BY ID),
                [Result2] = LAG(Result, 2) OVER(PARTITION BY TeamID ORDER BY ID),
                [Result3] = LAG(Result, 3) OVER(PARTITION BY TeamID ORDER BY ID),
                [Result4] = LAG(Result, 4) OVER(PARTITION BY TeamID ORDER BY ID)
        FROM    Results
    )
    SELECT  Home.ID,
            [Home(no.)] = Home.TeamID ,
            [Away(no.)] = Away.TeamID,
            [Result_Home] = Home.Result,
            [Result_Away] = Away.Result,
            [Home1] = Home.Result1,
            [Home2] = Home.Result2,
            [Home3] = Home.Result3,
            [Home4] = Home.Result4,
            [Away1] = Away.Result1,
            [Away2] = Away.Result2,
            [Away3] = Away.Result3,
            [Away4] = Away.Result4
    FROM    Results2 AS Home
            INNER JOIN results2 AS Away
                ON Away.ID = Home.ID
                AND Away.Type = 'Away'
    WHERE   Home.Type = 'Home'
    ORDER BY ID;
    

    Example on SQL Fiddle

    【讨论】:

      【解决方案2】:

      您似乎正在寻找 ROW_NUMBER() 函数或其他窗口函数

      类似

      ;with cte as 
      (
          select id, home as team, result_home as score from yourtable
          union
          select id, away, result_away from yourtable
      ),
      games as
      (
          select *, ROW_NUMBER() over (partition by team order by id) as gameday
          from cte
      )   
          select  *
          from (select team, score, gameday from games) src
          pivot
          (max(score) for gameday in ([1],[2],[3],[4],[5],[6]))p
      

      如果您知道每支球队的个人比赛比赛日,那么两场比赛前就是本场比赛的比赛日 - 2,依此类推。

      【讨论】:

        猜你喜欢
        • 2021-11-18
        • 2012-06-18
        • 2016-07-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-10
        • 2021-04-01
        • 2012-10-12
        相关资源
        最近更新 更多