w3resource

SQL Exercise: Which player was the first to be sent off at Euro 2016


15. From the following tables, write a SQL query to find the player who was the first player to be sent off at the tournament EURO cup 2016. Return match Number, country name and player name.

Sample table: player_booked

 match_no | team_id | player_id | booking_time | sent_off | play_schedule | play_half
----------+---------+-----------+--------------+----------+---------------+-----------
        1 |    1216 |    160349 |           32 |          | NT            |         1
        1 |    1216 |    160355 |           45 |          | NT            |         1
        1 |    1207 |    160159 |           69 | Y        | NT            |         2
        1 |    1216 |    160360 |           78 |          | NT            |         2
        2 |    1221 |    160470 |           14 |          | NT            |         1
        2 |    1201 |    160013 |           23 |          | NT            |         1
        2 |    1201 |    160013 |           36 |          | NT            |         1
        2 |    1201 |    160014 |           63 |          | NT            |         2
        2 |    1221 |    160472 |           66 |          | NT            |         2
.......
       51 |    1214 |    160302 |          122 |          | ET            |         2

View the table

Sample table: player_mast

 player_id | team_id | jersey_no |       player_name       | posi_to_play | dt_of_bir  | age |    playing_club
-----------+---------+-----------+-------------------------+--------------+------------+-----+---------------------
    160001 |    1201 |         1 | Etrit Berisha           | GK           | 1989-03-10 |  27 | Lazio
    160008 |    1201 |         2 | Andi Lila               | DF           | 1986-02-12 |  30 | Giannina
    160016 |    1201 |         3 | Ermir Lenjani           | MF           | 1989-08-05 |  26 | Nantes
    160007 |    1201 |         4 | Elseid Hysaj            | DF           | 1994-02-20 |  22 | Napoli
    160013 |    1201 |         5 | Lorik Cana              | MF           | 1983-07-27 |  32 | Nantes
    160010 |    1201 |         6 | Frederic Veseli         | DF           | 1992-11-20 |  23 | Lugano
    160004 |    1201 |         7 | Ansi Agolli             | DF           | 1982-10-11 |  33 | Qarabag
    160012 |    1201 |         8 | Migjen Basha            | MF           | 1987-01-05 |  29 | Como
    160017 |    1201 |         9 | Ledian Memushaj         | MF           | 1986-12-17 |  29 | Pescara
.........
160548 |    1224 |        23 | Simon Church            | FD           | 1988-12-10 |  27 | MK Dons

View the table

Sample table: soccer_country

 country_id | country_abbr |    country_name
------------+--------------+---------------------
       1201 | ALB          | Albania
       1202 | AUT          | Austria
       1203 | BEL          | Belgium
       1204 | CRO          | Croatia
       1205 | CZE          | Czech Republic
       1206 | ENG          | England
       1207 | FRA          | France
       1208 | GER          | Germany
       1209 | HUN          | Hungary
.......
       1229 | NOR          | Norway

View the table

Sample Solution:

SQL Code:

-- Selecting match_no, country_name, player_name, sent_off_time, play_schedule, and jersey_no for booked players who were sent off
SELECT match_no, country_name, player_name, 
       booking_time as "sent_off_time", play_schedule, jersey_no
-- From clause with JOINs between player_booked, player_mast, and soccer_country
FROM player_booked a
JOIN player_mast b ON a.player_id = b.player_id
JOIN soccer_country c ON a.team_id = c.country_id
-- Conditions for filtering booked players who were sent off
AND a.sent_off = 'Y'	
-- Condition for filtering matches with the minimum match_no among booked players
AND match_no = (
    SELECT MIN(match_no) 
    -- Subquery to find the minimum match_no among booked players
    FROM player_booked
)
-- Ordering the results by match_no, play_schedule, play_half, and booking_time
ORDER BY match_no, play_schedule, play_half, booking_time;

Sample Output:

 match_no | country_name |   player_name   | sent_off_time | play_schedule | jersey_no
----------+--------------+-----------------+---------------+---------------+-----------
        1 | France       | Olivier Giroud  |            69 | NT            |         9
(1 row)

Code Explanation:

The said query in SQL that selects information about players who have been sent off during a specific match. The specific match is determined by the subquery that returns the minimum match number.
The JOIN statements are used to link the tables player_booked, player_mast, and soccer_country together based on matching columns. The ON clauses specify the conditions for the join.
The WHERE clause filters the results to only include rows where the sent_off column in the player_booked table is equal to 'Y', and the match_no column in the player_booked table is equal to the minimum match number returned by the subquery.
The results are sorted in ascending order by match_no, play_schedule, play_half, and booking_time.

Alternative Solutions:

Using an Inner Join and Subquery:

-- Selecting match_no, country_name, player_name, sent_off_time, play_schedule, and jersey_no for booked players who were sent off
SELECT pb.match_no, sc.country_name, pm.player_name, 
       pb.booking_time AS "sent_off_time", pb.play_schedule, pm.jersey_no
-- From clause with JOINs between player_booked, player_mast, and soccer_country
FROM player_booked pb
JOIN player_mast pm ON pb.player_id = pm.player_id
JOIN soccer_country sc ON pb.team_id = sc.country_id
-- Joining with a subquery to filter matches with the minimum match_no among booked players
JOIN (
    SELECT MIN(match_no) AS min_match_no
    FROM player_booked
) min_match ON pb.match_no = min_match.min_match_no
-- Condition for filtering sent-off players
WHERE pb.sent_off = 'Y'
-- Ordering the results by match_no, play_schedule, play_half, and booking_time
ORDER BY pb.match_no, pb.play_schedule, pb.play_half, pb.booking_time;

Explanation:

This query uses an inner join with a subquery that finds the minimum match number. The join condition ensures that only the rows with the minimum match number are selected.

Using ROW_NUMBER() Window Function:

-- Selecting match_no, country_name, player_name, sent_off_time, play_schedule, and jersey_no for the earliest booked player who was sent off
SELECT match_no, country_name, player_name, 
       sent_off_time, play_schedule, jersey_no
-- From clause with a subquery (aliased as subquery) using ROW_NUMBER() window function
FROM (
    -- Subquery to select match_no, country_name, player_name, sent_off_time, play_schedule, jersey_no, and assign row numbers
    SELECT pb.match_no, sc.country_name, pm.player_name, 
           pb.booking_time AS sent_off_time, pb.play_schedule, pm.jersey_no,
           ROW_NUMBER() OVER (ORDER BY pb.match_no, pb.play_schedule, pb.play_half, pb.booking_time) as row_num
    -- From clause with JOINs between player_booked, player_mast, and soccer_country
    FROM player_booked pb
    JOIN player_mast pm ON pb.player_id = pm.player_id
    JOIN soccer_country sc ON pb.team_id = sc.country_id
    -- Condition for filtering sent-off players
    WHERE pb.sent_off = 'Y'
) subquery
-- Filtering the results to include only rows with row number equal to 1 (earliest booked player who was sent off)
WHERE row_num = 1;

Explanation:

This query uses a subquery with a ROW_NUMBER() window function to assign a unique number to each row based on the specified order. The outer query then selects only the rows with row number 1, effectively choosing the earliest occurrence for each match.

Go to:


PREV : Number of matches played at each venue and their city
NEXT : Teams that scored only one goal to the torunament.


Practice Online



Sample Database: soccer

soccer database relationship structure.


Have another way to solve this solution? Contribute your code (and comments) through Disqus.

What is the difficulty level of this exercise?

Test your Programming skills with w3resource's quiz.



Follow us on Facebook and Twitter for latest update.