This is a showcase of SQL queries run on a fictious database for a record selling company called Chinook Records.
I choose a SQLite 3 database as:
- it’s really simple to run on a simple computer, not needing to install a full solution such as MySQL, PostgreSQL etc.
- although there are certain functionalities not available on SQLlite, most of the SQL queries can be run on other variants
The example database was downloaded from the website SQLite Sample Database and below is the diagram of the DB.
The database is fairly simple:
- we have songs (tracks) that we sell to customers
- songs / tracks belong to an album, an artist and a genre and they have a specific type (ex: MP3, AAC etc.)
- customers buy tracks and we invoice them
- one invoice will have one or several lines corresponding to the number of tracks that we sold to that customer.
We’ll query the DB to get some insights into this company. Note that most of the queries are short, they’re only meant to go through certain operations:
- SELECT statement
- LIMIT results
- Filter, Group and order results
- Subqueries
- JOINS
- String formatting
- Date operations
- CTE
Examples of artists and albums
Let’s see first what we’re selling and to whom we are selling to.
SELECT *
FROM artists
LIMIT 10
ArtistId | Name |
---|---|
1 | AC/DC |
2 | Accept |
3 | Aerosmith |
4 | Alanis Morissette |
5 | Alice In Chains |
6 | Antônio Carlos Jobim |
7 | Apocalyptica |
8 | Audioslave |
9 | BackBeat |
10 | Billy Cobham |
Some of our customers
SELECT FirstName, LastName, Country
FROM customers
LIMIT 10
FirstName | LastName | Country |
---|---|---|
Luís | Gonçalves | Brazil |
Leonie | Köhler | Germany |
François | Tremblay | Canada |
Bjørn | Hansen | Norway |
František | Wichterlová | Czech Republic |
Helena | Holý | Czech Republic |
Astrid | Gruber | Austria |
Daan | Peeters | Belgium |
Kara | Nielsen | Denmark |
Eduardo | Martins | Brazil |
How about only the customers in Brazil?
SELECT FirstName, LastName, Country
FROM customers
WHERE Country = "Brazil"
LIMIT 10
FirstName | LastName | Country |
---|---|---|
Luís | Gonçalves | Brazil |
Eduardo | Martins | Brazil |
Alexandre | Rocha | Brazil |
Roberto | Almeida | Brazil |
Fernanda | Ramos | Brazil |
Top bands with the most number of albums
SELECT Name, total_albums
FROM artists
LEFT JOIN
(
SELECT ArtistId, count(ArtistId) AS total_albums
FROM albums
GROUP BY ArtistId
) AS total_albums
ON artists.ArtistId = total_albums.ArtistId
ORDER BY total_albums DESC
LIMIT 10
Name | total_albums |
---|---|
Iron Maiden | 21 |
Led Zeppelin | 14 |
Deep Purple | 11 |
Metallica | 10 |
U2 | 10 |
Ozzy Osbourne | 6 |
Pearl Jam | 5 |
Various Artists | 4 |
Faith No More | 4 |
Foo Fighters | 4 |
Top spenders
Let’s get a list of our top spenders.
SELECT Sum(I.Total) as Total_purchased,
C.FirstName,
UPPER(C.LastName)
FROM invoices I, customers C
WHERE I.CustomerId = C.CustomerId
GROUP BY C.LastName
ORDER BY Total_purchased DESC
LIMIT 10
Total_purchased | FirstName | UPPER(C.LastName) |
---|---|---|
49.62 | Helena | HOLý |
47.62 | Richard | CUNNINGHAM |
46.62 | Luis | ROJAS |
45.62 | Hugh | O’REILLY |
45.62 | Ladislav | KOVáCS |
43.62 | Julia | BARNETT |
43.62 | Fynn | ZIMMERMANN |
43.62 | Frank | RALSTON |
42.62 | Victor | STEVENS |
42.62 | Astrid | GRUBER |
Top sales by month
SELECT strftime('%Y-%m', InvoiceDate) as YearMonth,
SUM(Total)
FROM invoices
GROUP BY YearMonth
LIMIT 10
Note: strftime('%Y-%m', InvoiceDate)
is the SQLite3 equivalent of Year(InvoiceDate)
and Month(InvoiceDate)
YearMonth | SUM(Total) |
---|---|
2009-01 | 35.64 |
2009-02 | 37.62 |
2009-03 | 37.62 |
2009-04 | 37.62 |
2009-05 | 37.62 |
2009-06 | 37.62 |
2009-07 | 37.62 |
2009-08 | 37.62 |
2009-09 | 37.62 |
2009-10 | 37.62 |
The total of 37.62 repeats as the invoices were copy-pasted in the DB and only the date changed.
Top countries by total bought
Sales per country
SELECT BillingCountry, SUM("Total") as total_per_country
FROM invoices
GROUP BY BillingCountry
ORDER BY "total_per_country" DESC
LIMIT 10
BillingCountry | total_per_country |
---|---|
USA | 523.06 |
Canada | 303.96 |
France | 195.1 |
Brazil | 190.1 |
Germany | 156.48 |
United Kingdom | 112.86 |
Czech Republic | 90.24 |
Portugal | 77.24 |
India | 75.26 |
Chile | 46.62 |
Top countries with sales higher than the average
WITH average_per_country (avg_per_country) AS (
SELECT AVG("Total") as avg_per_country
FROM invoices
)
SELECT BillingCountry, AVG("Total") as total_per_country
FROM invoices, average_per_country
GROUP BY BillingCountry
HAVING (total_per_country > average_per_country.avg_per_country)
BillingCountry | total_per_country |
---|---|
Austria | 6.08857142857143 |
Chile | 6.66 |
Czech Republic | 6.44571428571429 |
Finland | 5.94571428571429 |
Hungary | 6.51714285714286 |
India | 5.78923076923077 |
Ireland | 6.51714285714286 |
Netherlands | 5.80285714285714 |
Norway | 5.66 |
USA | 5.74791208791209 |