New month, new goals. Your help keeps the project moving forward. 🖥️ Support sqltest →
SQL code copied to buffer

Bookings database: airline schema, tables and SQL exercises

Bookings is the PostgreSQL demo database of an airline: flights between 104 airports, bookings, tickets and boarding passes. On SQLtest.online you can query it right in your browser: solve exercises with automatic checking and run your own queries in the playground, with nothing to install.

  • 8 tables and 4 views
  • 33,121 flights
  • 1,045,726 tickets × flights
  • 52 SQL exercises

What is Bookings

Bookings is the demo database that Postgres Professional publishes for learning PostgreSQL. It models the flights of a Russian airline: routes, aircraft and their seat maps, bookings, tickets and boarding passes.

This copy holds flights from July to September 2017. Airport and aircraft names are stored as JSONB in English and Russian, and airport coordinates use the PostgreSQL point type, so the database is good for practicing PostgreSQL-specific SQL as well as JOINs and analytics on large tables.

ER diagram

The diagram shows the Bookings tables and the foreign keys between them. Click it to open the full-size version.

ER diagram of the Bookings database

What's inside

The tables fall into two groups.

Reference data

airports_data, aircrafts_data and seats: the seat map of each aircraft model.

Sales and flights

bookings → tickets → ticket_flights ← flights, plus boarding_passes issued at check-in.

The key thing to remember: one booking can include several passengers, and one ticket can cover several flights. The link between tickets and flights is ticket_flights, the largest table. The views aircrafts, airports, flights_v and routes show the same data in a friendlier form.

How much data the tables hold:

TableRowsContents
bookings262,788bookings
tickets366,733tickets, one per passenger
ticket_flights1,045,726flight segments of tickets
boarding_passes579,686boarding passes
flights33,121scheduled and performed flights
airports_data104airports
aircrafts_data9aircraft models
seats1,339seats by aircraft model

Table structure

Click a table to see its columns, a sample row and its keys.

The list of tables

aircrafts_data - table of aircrafts.
  • aircraft_codeUnique code for each aircraft
  • modelAircraft model name in English and Russian in JSON format
  • rangeAircraft fly range in kilometers
  • PRIMARY KEY, btree (aircraft_code)
aircraft_codemodelrange
1773{"en": "Boeing 777-300", "ru": "Боинг 777-300"}11100
airports_data - table of airports.
  • airport_codeUnique code for each airport
  • airport_nameAirport name in English and Russian in JSON format
  • cityAirport city in English and Russian in JSON format
  • coordinatesAirport coordinates as POINT(longitude, latitude)
  • timezoneAirport timezone name
  • PRIMARY KEY, btree (airport_code)
airport_codeairport_namecitycoordinatestimezone
1YKS{"en": "Yakutsk Airport", "ru": "Якутск"}{"en": "Yakutsk", "ru": "Якутск"}(129.77099609375,62.0932998657227)Asia/Yakutsk
boarding_passes - table of boarding passes.
  • ticket_noTicket number
  • flight_idFlight identificator
  • boarding_noBoarding pass number
  • seat_noSeat number
  • PRIMARY KEY, btree (ticket_no, flight_id)
  • UNIQUE CONSTRAINT, btree (flight_id, boarding_no)
  • UNIQUE CONSTRAINT, btree (flight_id, seat_no)
  • FOREIGN KEY (ticket_no, flight_id) REFERENCES ticket_flights(ticket_no, flight_id)
ticket_noflight_idboarding_noseat_no
100054352123513062512D
bookings - table of bookings.
  • book_refBooking number
  • book_dateBooking date
  • total_amountTotal booking cost
  • PRIMARY KEY, btree (book_ref)
book_refbook_datetotal_amount
100000F2017-07-05 00:12:00+00265700.00
flights - table of flights.
  • flight_idFlight ID
  • flight_noFlight number
  • scheduled_departureScheduled departure time
  • scheduled_arrivalScheduled arrival time
  • departure_airportAirport of departure
  • arrival_airportAirport of arrival
  • statusFlight status
  • aircraft_codeAircraft code, IATA
  • actual_departureActual departure time
  • actual_arrivalActual arrival time
  • PRIMARY KEY, btree (flight_id)
  • UNIQUE CONSTRAINT, btree (flight_no, scheduled_departure)
flight_id flight_no scheduled_departure scheduled_arrival departure_airport arrival_airport status aircraft_code actual_departure actual_arrival
11185PG01342017-09-10 06:50:00+002017-09-10 11:55:00+00DMEBTKScheduled319
seats - table of aircraft seats.
  • aircraft_codeAircraft code, IATA
  • seat_noSeat number
  • fare_conditionsTravel class
  • PRIMARY KEY, btree (aircraft_code, seat_no)
  • FOREIGN KEY (aircraft_code) REFERENCES aircrafts(aircraft_code) ON DELETE CASCADE
aircraft_codeseat_nofare_conditions
13192ABusiness
ticket_flights - ticket to flights relations.
  • ticket_noTicket number
  • flight_idFlight ID
  • fare_conditionsTravel class
  • amountTravel cost
  • PRIMARY KEY, btree (ticket_no, flight_id)
  • FOREIGN KEY (flight_id) REFERENCES flights(flight_id)
  • FOREIGN KEY (ticket_no) REFERENCES tickets(ticket_no)
ticket_no flight_id fare_conditions amount
1000543215977630625Business42100.00
tickets - table of tickets.
  • ticket_noTicket number
  • book_refBooking number
  • passenger_idPassenger ID
  • passenger_namePassenger name
  • contact_dataPassenger contact information
ticket_no book_ref passenger_id passenger_name contact_data
1000543200098706B0468149 604011VALERIY TIKHONOV{"phone": "+70127117011"}
  • PRIMARY KEY, btree (ticket_no)
  • FOREIGN KEY (book_ref) REFERENCES bookings(book_ref)

Sample queries

These queries show how the data is connected. Copy any of them and run it in the playground.

A ticket and its booking: the passenger and the booking amount.

SELECT t.ticket_no, t.passenger_name, b.book_date, b.total_amount
FROM tickets t
JOIN bookings b ON b.book_ref = t.book_ref
ORDER BY t.ticket_no
LIMIT 3;
ticket_nopassenger_namebook_datetotal_amount
0005432000987VALERIY TIKHONOV2017-07-05 17:19:00+0012400.00
0005432000988EVGENIYA ALEKSEEVA2017-07-05 17:19:00+0012400.00
0005432000989ARTUR GERASIMOV2017-06-28 22:55:00+0024700.00

A flight and its aircraft: reading an English name from a JSONB column with ->>.

SELECT f.flight_no, f.departure_airport, f.arrival_airport,
       a.model ->> 'en' AS aircraft
FROM flights f
JOIN aircrafts_data a ON a.aircraft_code = f.aircraft_code
ORDER BY f.flight_id
LIMIT 3;
flight_nodeparture_airportarrival_airportaircraft
PG0405DMELEDAirbus A321-200
PG0404DMELEDAirbus A321-200
PG0405DMELEDAirbus A321-200

Fare and seat: from a ticket segment to its flight and boarding pass. The LEFT JOIN keeps segments without a boarding pass.

SELECT tf.ticket_no, f.flight_no, tf.fare_conditions, tf.amount, bp.seat_no
FROM ticket_flights tf
JOIN flights f ON f.flight_id = tf.flight_id
LEFT JOIN boarding_passes bp
       ON bp.ticket_no = tf.ticket_no AND bp.flight_id = tf.flight_id
ORDER BY tf.ticket_no, f.flight_id
LIMIT 3;
ticket_noflight_nofare_conditionsamountseat_no
0005432000987PG0242Economy6200.007A
0005432000988PG0242Economy6200.0010E
0005432000989PG0242Economy6200.0018E

SQL exercises by topic

There are 52 exercises on the Bookings database, from simple lookups to analytics over a million rows. Solutions are checked automatically on a real PostgreSQL server. The number on the right is how many exercises a topic has; the colored dots show its difficulty range.

Where to start

The first exercises on the Bookings database:

  1. Get airports data
  2. Airports List
  3. Long-Range Aircrafts
  4. Find Boeing aircraft
  5. Flights Departed from Domodedovo
  6. List Aircraft from Domodedovo
  7. Get Bookings by Date
  8. Aircraft usage analysis
  9. Fare Conditions Types
  10. Aircraft Lacking Business Class Seats

All Bookings exercises →

FAQ

Do I need to install PostgreSQL to use the Bookings database?

No. The exercises and the playground on SQLtest.online run your queries on our servers, so a browser is all you need. In the playground, Bookings is available on PostgreSQL 18.

Where can I download the Bookings demo database?

Postgres Professional publishes it in several sizes on its website, together with a description of the schema.

Why are some names in curly braces?

Airport, city and aircraft names are JSONB objects with English and Russian values. Use ->> 'en' to get the English text, or query the views, which pick one language.