Skip to content
Advertisement

SQL Server : select first occurrence from two columns

(Edit: I am bound to use Visual Studio 19 and have no rights to install any other application)

I have a small SQL table with about 150k rows and 20 columns which I need to modify.

  1. I need the table to be ordered by date.
  2. I need the first occurrence of a value from two columns.
  3. Depending on if the value first occurred in column Home_Team or Away_Team, I need the column Home_Elo or Away_Elo modified to 1500.
  4. Copy into a new table.

I get the 1st part and 4th, but already have struggles getting the first occurrence from to columns – not even tried 3rd.

SELECT * 
INTO New_Table
FROM
    (SELECT 
         *,
         ROW_NUMBER() OVER (PARTITION BY Home_Team, Away_Team ORDER BY Date ASC) rn
     FROM   
         Matches) t
WHERE rn = 1

Sadly this not only orders by Home_Team, but also returns the first occurrence of both values.

I guess I need OR instead of AND (is that possible in SQL Server?)

ID; Home_Team; Away_Team; Date;       Home_Elo; Away_Elo;
1;  Turku;     Haka;      13.09.1999;
2;  Pori;      Turku;     12.09.1999;
3;  Joker;     Rovaniemi; 10.09.1999;
4;  TeePee;    MyPa;      11.09.1999;
5;  Joker;     TeePee;    20.09.1999;
6;  Rovaniemi; Joker;     12.09.1999;

Desired:
ID; Home_Team; Away_Team; Date;       Home_Elo; Away_Elo;
3;  Joker;     Rovaniemi; 10.09.1999; 1500;     1500;
4;  TeePee;    Rovaniemi; 11.09.1999; 1500;     
2;  Pori;      Turku;     12.09.1999; 1500;     1500;
6;  Rovaniemi; Joker;     12.09.1999;
1;  Turku;     Haka;      13.09.1999;           1500;
5;  Joker;     TeePee;    20.09.1999;

Advertisement

Answer

Apply row_number() to the union of home and away teams and join to the table:

select m.id, m.home_team, m.away_team, m.date,
  max(case t.rn when 1 then case homeaway when 1 then 1500 end end) home_elo,
  max(case t.rn when 1 then case homeaway when 2 then 1500 end end) away_elo
from matches m inner join (
  select u.*,
    row_number() over (partition by team order by date) rn
  from (
    select 1 homeaway, home_team team, date from matches
    union all
    select 2, away_team, date from matches
  ) u
) t on t.date = m.date and t.team in (m.home_team, m.away_team)
group by m.id, m.home_team, m.away_team, m.date
order by m.date, m.home_team, m.away_team

See the demo.
Results:

> id | home_team | away_team | date       | home_elo | away_elo
> -: | :-------- | :-------- | :--------- | -------: | -------:
>  3 | Joker     | Rovaniemi | 10.09.1999 |     1500 |     1500
>  4 | TeePee    | Rovaniemi | 11.09.1999 |     1500 |     
>  2 | Pori      | Turku     | 12.09.1999 |     1500 |     1500
>  6 | Rovaniemi | Joker     | 12.09.1999 |          |     
>  1 | Turku     | Haka      | 13.09.1999 |          |     1500
>  5 | Joker     | TeePee    | 20.09.1999 |          |     
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement