Question

I am trying to build reports for sport team. The results are stored in a SQL-Database like this: Table

For the reports I need the columns Home2-Away4 to be filled with the corresponding results. Which means:

Imagine: ID=10 and Home(no.) (Team#) = 1 --> Home1 = result one game before which is ID=3 and the team played away and the result was 0 (=home1). This is what I already have done, but Home2 = result two games ago, as Home3=result three games ago and so on.

And here is how I have done this:

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 btw.)

I have written a small Java code which decides if to pick from result_home or result_away.

The basic question is: How is it possible to query for game results two and more gamedays ago?

Thanks in advance.

Kind regards

Stefan

Was it helpful?

Solution

I think you need the LAG function. The simplest case would be something like:

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

However, it is not quite as simple as this because you need to reference home or away, so you need to first unpivot your data

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

This means you can access each teams result whether it is home or away all in one column (For the lag function).

Then with this unpivoted data you apply the lag to get the previous 4 results (I've used ORDER BY ID but I'd assume there is a date field I am missing?):

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)

Then once you have each teams previous 4 results for each match you can join the unpivoted data back together to get the home and away teams on the same row again, giving the full query:

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

OTHER TIPS

It looks like you're looking for the ROW_NUMBER() function or another windowing function

Something like

;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

If you know an individual games gameday for each team, then two games ago is this games' gameday - 2, etc.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top