0

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

对于报告,我需要用相应的结果填充 Home2-Away4 列。意思是:

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

这是我如何做到的:

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 

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

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

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

提前致谢。

亲切的问候

斯特凡

4

2 回答 2

2

我认为您需要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;

SQL Fiddle 示例

于 2012-10-31T14:48:00.843 回答
0

看起来您正在寻找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,依此类推。

于 2012-10-31T14:42:32.987 回答