Advanced SQL Queries for Database Analytics
This document presents a collection of practical SQL queries designed to extract valuable insights from a database, likely a music store schema such as Chinook. Each query demonstrates different SQL concepts, from basic data retrieval to complex joins, subqueries, and aggregations, providing solutions for common business questions.
- Top 10 Customers by Spending (Over $40)- Identifies the top 10 customers who have spent more than $40 in total, ordered by their total expenditure in descending order. - SELECT c.customerid, c.firstname, c.lastname, SUM(i.total) AS total_spent FROM customer c JOIN invoice i ON c.customerid = i.customerid GROUP BY c.customerid, c.firstname, c.lastname HAVING SUM(i.total) > 40 ORDER BY total_spent DESC LIMIT 10;
- Customers in Cities with Invoices- Retrieves all customer details for individuals residing in cities where at least one invoice has been issued. - SELECT * FROM customer c WHERE c.city IN ( SELECT DISTINCT billingcity FROM invoice );
- Tracks by The Beatles from ‘WHITE’ Album- Finds all track details for songs by ‘The Beatles’ specifically from their album titled ‘WHITE’. - SELECT * FROM track t JOIN album al ON t.albumid = al.albumid JOIN artist ar ON al.artistid = ar.artistid WHERE al.title = 'WHITE' AND ar.name = 'The Beatles' ;
- Customers Who Purchased ‘Grunge’ Playlist Tracks- Lists distinct customers who have purchased any track that is part of the ‘Grunge’ playlist. - SELECT DISTINCT c.customerid, c.firstname, c.lastname FROM customer c JOIN invoice i ON c.customerid = i.customerid JOIN invoiceline il ON i.invoiceid = il.invoiceid JOIN track t ON il.trackid = t.trackid JOIN playlisttrack pt ON t.trackid = pt.trackid JOIN playlist pl ON pt.playlistid = pl.playlistid WHERE pl.name = 'Grunge' ;
- Composer Song Counts- Counts the number of songs for each composer, excluding tracks where the composer is not specified. - SELECT composer, COUNT(*) AS num_songs FROM track WHERE composer IS NOT NULL GROUP BY composer ;
- Albums with Over 10 Tracks- Identifies albums that contain more than 10 tracks, displaying the album title and the total count of tracks. - SELECT DISTINCT a.title, COUNT(t.trackid) AS num_songs FROM album a JOIN track t ON a.albumid = t.albumid GROUP BY a.albumid , a.title HAVING COUNT(t.trackid) > 10 ;
- Composer Song Counts by Genre- Provides a breakdown of song counts for each composer, categorized by genre, for tracks with a specified composer. - SELECT t.composer, g.name, COUNT(*) AS num_songs FROM track t JOIN genre g ON t.genreid = g.genreid WHERE t.composer IS NOT NULL GROUP BY t.composer, g.name ;
- Top Selling Tracks by Composer- Lists tracks, their composers, and the total quantity sold, ordered by total sales in descending order. - SELECT t.name, t.composer, SUM(il.quantity) AS total_sales FROM track t JOIN invoiceline il ON t.trackid = il.trackid WHERE t.composer IS NOT NULL GROUP BY t.trackid, t.name, t.composer ORDER BY total_sales DESC ;
- Total Sales by Country- Calculates the aggregate quantity of products sold for each customer’s country. - SELECT c.country, SUM(il.quantity) AS total_sales FROM customer c JOIN invoice i ON c.customerid = i.customerid JOIN invoiceline il ON i.invoiceid = il.invoiceid GROUP BY c.country ;
- Employees Supporting Max Invoice Customers- Retrieves details of employees who support customers with the highest single invoice total. - SELECT e.*, i.total FROM employee e JOIN customer c ON e.employeeid = c.supportrepid JOIN invoice i ON c.customerid = i.customerid WHERE i.total = ( SELECT MAX(total) FROM invoice) ;
- Playlists with Most Expensive or Longest Track- Identifies playlists that contain either the single most expensive track or the single longest track (by milliseconds). - SELECT pl.name FROM playlist pl JOIN playlisttrack pt ON pl.playlistid = pt.playlistid JOIN track t ON pt.trackid = t.trackid WHERE t.trackid = ( SELECT trackid FROM track ORDER BY unitprice DESC LIMIT 1 ) OR t.trackid = ( SELECT trackid FROM track ORDER BY milliseconds DESC LIMIT 1 ) ;
- Unsold Tracks with Discounted Price- Lists tracks that have never been sold, showing their original price and a new price with a 20% discount. - SELECT t.trackid, t.name, t.unitprice AS original_price, ROUND(t.unitprice * 0.8, 2) AS discounted_price FROM track t LEFT JOIN invoiceline il ON t.trackid = il.trackid WHERE il.trackid IS NULL ;
- Customers with a Single Invoice- Retrieves customer details and their invoice dates for customers who have only one invoice recorded. - SELECT c.customerid, CONCAT(c.lastname, ', ', c.firstname) AS customer_details, i.invoicedate FROM customer c JOIN invoice i ON c.customerid = i.customerid WHERE c.customerid IN ( SELECT customerid FROM invoice GROUP BY customerid HAVING COUNT(*) = 1 ) ;
- Customers and Employees Outside UK- Combines a list of customers and employees who are not from the United Kingdom, indicating their type (Customer/Employee). - SELECT c.firstname AS first_name, c.lastname AS last_name, 'Customer' AS person_type FROM customer c WHERE c.country NOT LIKE 'United Kingdom' UNION SELECT e.firstname AS first_name, e.lastname AS last_name, 'Employee' AS person_type FROM employee e WHERE e.country NOT LIKE 'UK' ORDER BY first_name, last_name ;
- Employee Sales Performance (May 2025)- Analyzes employee sales performance for May 2025, counting distinct invoices and tracks sold, for employees with more than 5 distinct invoices. - SELECT e.firstname, e.lastname, COUNT(DISTINCT i.invoiceid) AS num_invoices, COUNT(DISTINCT il.trackid) AS num_distinct_tracks FROM employee e JOIN customer c ON e.employeeid = c.supportrepid JOIN invoice i ON c.customerid = i.customerid JOIN invoiceline il ON i.invoiceid = il.invoiceid WHERE i.invoicedate BETWEEN '2025-05-01' AND '2025-05-31' GROUP BY e.employeeid, e.firstname, e.lastname HAVING COUNT(DISTINCT i.invoiceid) > 5 ;
- Top 10 Customers by Products & Spending- Identifies the top 10 customers based on total products purchased and total spending, for those with at least 6 invoices and over $40 total spent. - SELECT c.firstname, c.lastname, SUM(il.quantity) AS total_products, SUM(i.total) AS total_spent FROM customer c JOIN invoice i ON c.customerid = i.customerid JOIN invoiceline il ON i.invoiceid = il.invoiceid GROUP BY c.customerid, c.firstname, c.lastname HAVING COUNT(DISTINCT i.invoiceid) >= 6 AND SUM(i.total) > 40 ORDER BY total_products DESC, total_spent DESC LIMIT 10 ;
- Customers with Invoices After John Smith’s First- Lists customers who have invoices dated after the earliest invoice date of ‘John Smith’. - SELECT c.customerid, CONCAT(c.firstname, ', ', c.lastname) AS full_name, c.country, c.state, c.city FROM customer c JOIN invoice i ON c.customerid = i.customerid WHERE i.invoicedate > (SELECT MIN(i2.invoicedate) FROM customer c2 JOIN invoice i2 ON c2.customerid = i2.customerid WHERE c2.firstname = 'John' AND c2.lastname = 'Smith') GROUP BY c.customerid, c.firstname, c.lastname, c.country, c.state, c.city ORDER BY c.country, c.state, c.city ;
