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.

  1. 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;
  2. 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
    );
  3. 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'
    ;
  4. 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'
    ;
  5. 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
    ;
  6. 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
    ;
  7. 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
    ;
  8. 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
    ;
  9. 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
    ;
  10. 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)
    ;
  11. 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
    )
    ;
  12. 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
    ;
  13. 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
    )
    ;
  14. 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
    ;
  15. 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
    ;
  16. 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
    ;
  17. 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
    ;