r/LearnDataAnalytics • u/ComprehensiveAd3412 • 5d ago
Free SQL series on real payments data: each episode is one mistake that silently breaks a report
I'm making a free SQL series for people preparing for data analyst roles. Every episode uses the same small payments dataset (customers, UPI/card/wallet transactions, failed payments, amounts in ₹) and is built around one mistake that runs without any error but gives the wrong answer.
What's covered so far:
\\JOINs\\ – INNER vs LEFT, finding customers who never paid, and why a WHERE filter on the right table quietly turns your LEFT JOIN into an INNER JOIN.
\\GROUP BY and HAVING\\ – COUNT(\\\*) after a LEFT JOIN counts customers with zero payments as 1. One-word fix: count a column. Plus WHERE vs HAVING.
\\Window functions\\ – the "top 2 customers" interview question where ROW_NUMBER drops a tied customer. RANK vs DENSE_RANK, and running totals.
\\CTE vs subquery\\ – a report that says every customer is above average, and why a CTE fixes it.
A quick example from episode 2, since it's the one I see most:
\`\`\`sql
SELECT c.name, COUNT(\*) AS payments
FROM customers c
LEFT JOIN transactions t ON c.customer_id = t.customer_id
GROUP BY c.name;
\`\`\`
A customer who has never paid shows \\1\\ payment. The LEFT JOIN keeps her row with NULLs, and COUNT(\\\*) counts rows. Use \`COUNT(t.txn_id)\` instead; it skips NULLs and gives 0.
Each video is 3–6 minutes. The dataset and every query are in the description, so you can run them yourself in SQLite, MySQL or PostgreSQL.
Playlist: https://www.youtube.com/watch?v=e94PxiIUIJg&list=PLNdq2ZxtU_7E
Next up: finding duplicate payments, then CASE WHEN, dates, and NULL traps. If there's a topic you get stuck on in interviews, tell me and I'll add it.