Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

7 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🎡 SQL Music Store Analysis

Answering real business questions for a digital music store using PostgreSQL


PostgreSQL SQL Difficulty Status


What does a real analyst actually do with a database? They ask business questions - and then write the SQL to answer them precisely. This project does exactly that, across 11 progressively complex queries on a live music store schema.


πŸ“Œ Overview

SQL Music Store Analysis is a business intelligence project built entirely in SQL on a relational music store database. It covers three tiers of analytical complexity - from basic aggregations to advanced window functions and recursive CTEs - producing actionable insights on sales performance, customer behaviour, artist popularity, and market penetration by country.

This project demonstrates not just SQL syntax, but the analyst's mindset: translating business problems into queries, and queries into decisions.


πŸ—„οΈ Database Schema

The analysis runs on an 11-table relational schema covering the full music store lifecycle:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   employee   β”‚     β”‚   customer   β”‚     β”‚    artist    β”‚
│──────────────│     │──────────────│     │──────────────│
β”‚ employee_id  β”‚     β”‚ customer_id  β”‚     β”‚  artist_id   β”‚
β”‚ first_name   β”‚     β”‚ first_name   β”‚     β”‚  name        β”‚
β”‚ last_name    β”‚     β”‚ last_name    β”‚     β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ title        β”‚     β”‚ email        β”‚            β”‚
β”‚ levels       β”‚     β”‚ country      β”‚     β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚    album     β”‚
                            β”‚             │──────────────│
                     β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”     β”‚  album_id    β”‚
                     β”‚   invoice    β”‚     β”‚  title       β”‚
                     │──────────────│     β”‚  artist_id   β”‚
                     β”‚ invoice_id   β”‚     β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚ customer_id  β”‚            β”‚
                     β”‚ billing_city β”‚     β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”
                     β”‚ total        β”‚     β”‚    track     β”‚
                     β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜     │──────────────│
                            β”‚             β”‚  track_id    β”‚
                     β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”     β”‚  name        β”‚
                     β”‚ invoice_line β”‚     β”‚  album_id    β”‚
                     │──────────────│     β”‚  genre_id    β”‚
                     β”‚ invoice_id   β”‚     β”‚  millisecondsβ”‚
                     β”‚ track_id     β”œβ”€β”€β”€β”€β”€β”‚  unit_price  β”‚
                     β”‚ unit_price   β”‚     β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚ quantity     β”‚            β”‚
                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”
                                          β”‚    genre     β”‚
                                          │──────────────│
                                          β”‚  genre_id    β”‚
                                          β”‚  name        β”‚
                                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Database Schema


πŸ” Business Questions Answered

The queries are structured across three difficulty levels, each with increasing analytical complexity.


🟒 Level 1 - Easy: Operational Queries

# Business Question SQL Concepts Used
Q1 Who is the most senior employee? ORDER BY, LIMIT
Q2 Which countries generate the most invoices? GROUP BY, COUNT, ORDER BY
Q3 What are the top 3 highest invoice values? ORDER BY DESC, LIMIT
Q4 Which city should we host the music festival in? SUM, GROUP BY, ORDER BY
Q5 Who is our single best (highest-spending) customer? JOIN, SUM, GROUP BY

Sample Query - Best City for a Music Festival:

SELECT billing_city, SUM(total) AS InvoiceTotal
FROM invoice
GROUP BY billing_city
ORDER BY InvoiceTotal DESC
LIMIT 1;

🟑 Level 2 - Moderate: Customer & Genre Intelligence

# Business Question SQL Concepts Used
Q1 Who are all the Rock music listeners? (email list) Multi-table JOIN, DISTINCT, Subquery
Q2 Which are the top 10 rock bands by track count? 4-table JOIN, COUNT, GROUP BY
Q3 Which tracks are longer than the average song length? Scalar Subquery, AVG, WHERE

Sample Query - Top 10 Rock Artists:

SELECT artist.name, COUNT(artist.artist_id) AS number_of_songs
FROM track
JOIN album   ON album.album_id   = track.album_id
JOIN artist  ON artist.artist_id = album.artist_id
JOIN genre   ON genre.genre_id   = track.genre_id
WHERE genre.name LIKE 'Rock'
GROUP BY artist.artist_id
ORDER BY number_of_songs DESC
LIMIT 10;

πŸ”΄ Level 3 - Advanced: Window Functions, CTEs & Recursive Queries

# Business Question SQL Concepts Used
Q1 How much did each customer spend on the top-selling artist? WITH CTE, 6-table JOIN, SUM, aggregation
Q2 What is the most popular genre in each country? WITH CTE + ROW_NUMBER() window function; also solved with Recursive CTE
Q3 Who is the top-spending customer in each country? WITH CTE + ROW_NUMBER() window function; also solved with Recursive CTE

Sample Query - Most Popular Genre Per Country (CTE + Window Function):

WITH popular_genre AS (
    SELECT
        COUNT(invoice_line.quantity)  AS purchases,
        customer.country,
        genre.name,
        genre.genre_id,
        ROW_NUMBER() OVER(
            PARTITION BY customer.country
            ORDER BY COUNT(invoice_line.quantity) DESC
        ) AS RowNo
    FROM invoice_line
    JOIN invoice  ON invoice.invoice_id   = invoice_line.invoice_id
    JOIN customer ON customer.customer_id = invoice.customer_id
    JOIN track    ON track.track_id       = invoice_line.track_id
    JOIN genre    ON genre.genre_id       = track.genre_id
    GROUP BY customer.country, genre.name, genre.genre_id
)
SELECT * FROM popular_genre WHERE RowNo <= 1;

πŸ’‘ SQL Techniques Demonstrated

Technique Used In
GROUP BY + HAVING Sales aggregation, customer ranking
Multi-table JOIN (up to 6 tables) Customer–invoice–track–artist chains
Correlated & scalar subqueries Track length filtering, top-N selection
Common Table Expressions (CTEs) Advanced Q1, Q2, Q3
Window functions - ROW_NUMBER() OVER (PARTITION BY ...) Top genre/customer per country
Recursive CTEs Alternative solutions for Q2 & Q3
DISTINCT for deduplication Email list generation
Aggregate functions - SUM, COUNT, AVG, MAX Throughout all levels

πŸ“ Repository Structure

SQL-Music-Store-Analysis/
β”‚
β”œβ”€β”€ πŸ—ƒοΈ  Music_Store_database.sql     ← Full database: schema + seed data
β”œβ”€β”€ πŸ”  Music_Store_Query.sql        ← All 11 analytical queries (3 difficulty levels)
β”œβ”€β”€ πŸ–ΌοΈ  MusicDatabaseSchema.png      ← Visual ER diagram of all 11 tables
└── πŸ“„  README.md                    ← You are here

πŸš€ Getting Started

Prerequisites

  • PostgreSQL 13+ (recommended) - or any SQL-compatible RDBMS

1. Clone the Repository

git clone https://github.com/AmanManiTiwari/SQL-Music-Store-Analysis.git
cd SQL-Music-Store-Analysis

2. Create the Database

-- In psql terminal
CREATE DATABASE music_store;
\c music_store

3. Load Schema & Data

psql -U postgres -d music_store -f Music_Store_database.sql

4. Run the Queries

psql -U postgres -d music_store -f Music_Store_Query.sql

Or open Music_Store_Query.sql in pgAdmin, DBeaver, or any SQL IDE and run queries section by section.


πŸ“ˆ Key Business Insights Unlocked

πŸ™οΈ Best city for a music festival - identified by aggregating total invoice revenue per billing city

πŸ‘‘ Best customer - found by joining customer and invoice tables and ranking by total spend

🎸 Top 10 rock bands - ranked by track catalogue size via a 4-table join chain

🌍 Most popular genre per country - solved two ways: using ROW_NUMBER() windowing and a recursive CTE, demonstrating SQL flexibility

πŸ’° Top spender per country - window function partitioned by country delivers country-level customer leaderboards in a single query


πŸ› οΈ Tools & Environment

Tool Purpose
PostgreSQL Primary database engine
pgAdmin / DBeaver Query execution & result visualization
SQL All analysis - no Python or BI tools

πŸ’Ό Real-World Relevance

The skills exercised here directly map to day-to-day analyst work at companies like:

  • Spotify / Apple Music - genre popularity by region, artist performance analytics
  • Retail & e-commerce - top customer identification, city-level revenue analysis
  • Any data team - writing clean, performant SQL that answers stakeholder questions without ambiguity

πŸ™‹ About the Author

Aman Mani Tiwari - Data analyst building a portfolio that spans SQL, Excel dashboards, and machine learning.

GitHub


If this project was useful, a ⭐ helps others find it - thank you!

About

A SQL-based business analysis of a digital music store database, using PostgreSQL queries to uncover top-selling tracks, customer spending patterns, and employee sales performance for data-driven insights.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors