CASE & Conditional Aggregation in SQL
CASE & Conditional Aggregation in SQL
If you ask any working data analyst in India what SQL feature they reach for most often, CASE will be near the top of the list. It is the closest thing SQL has to an "if-else", and once you combine it with aggregate functions like SUM, COUNT, and AVG, you can turn messy transactional tables into clean, report-ready summaries without leaving the database.
This guide walks through CASE in SELECT, then the real power move: conditional aggregation (pivoting rows into columns). Examples use the kind of data you would actually see at a Zomato, Flipkart, or your neighbourhood kirana store.
The CASE Expression in 60 Seconds
CASE has two forms. The searched form (most flexible) evaluates conditions top to bottom and returns the first match:
SELECT
order_id,
order_amount,
CASE
WHEN order_amount >= 5000 THEN 'High Value'
WHEN order_amount >= 1000 THEN 'Mid Value'
ELSE 'Low Value'
END AS order_tier
FROM orders;
The simple form compares one expression to several values:
SELECT
payment_mode,
CASE payment_mode
WHEN 'UPI' THEN 'Digital'
WHEN 'Card' THEN 'Digital'
WHEN 'COD' THEN 'Cash'
ELSE 'Other'
END AS payment_group
FROM orders;
Key rules to remember:
- Conditions are evaluated in order. Put the most specific (narrowest) condition first.
- If no
WHENmatches and there is noELSE,CASEreturnsNULL. - Every branch must return a compatible data type. Mixing text and numbers will error or implicitly cast.
CASE Inside SELECT: Labels and Buckets
The most common everyday use is bucketing a continuous value. Say you want to segment Flipkart customers by their lifetime spend:
SELECT
customer_id,
SUM(order_amount) AS lifetime_value,
CASE
WHEN SUM(order_amount) >= 50000 THEN 'Platinum'
WHEN SUM(order_amount) >= 20000 THEN 'Gold'
WHEN SUM(order_amount) >= 5000 THEN 'Silver'
ELSE 'Bronze'
END AS customer_segment
FROM orders
GROUP BY customer_id;
Notice you can use an aggregate (SUM(order_amount)) inside CASE as long as you are in a grouped query. The CASE runs after aggregation, so it sees the grouped total.
Conditional Aggregation: The Real Superpower
Here is the trick that separates beginners from analysts. By putting CASE inside an aggregate, you can count or sum only the rows that match a condition. The pattern is:
SUM(CASE WHEN <condition> THEN <value> ELSE 0 END)
COUNT(CASE WHEN <condition> THEN 1 END)
For SUM, non-matching rows contribute 0. For COUNT, non-matching rows return NULL, and COUNT ignores NULL - so you do not even need an ELSE.
Example: Payment Mode Breakdown in One Row
Instead of running three separate queries, get a single summary row per day:
SELECT
order_date,
COUNT(*) AS total_orders,
SUM(CASE WHEN payment_mode = 'UPI' THEN order_amount ELSE 0 END) AS upi_revenue,
SUM(CASE WHEN payment_mode = 'Card' THEN order_amount ELSE 0 END) AS card_revenue,
SUM(CASE WHEN payment_mode = 'COD' THEN order_amount ELSE 0 END) AS cod_revenue,
COUNT(CASE WHEN payment_mode = 'UPI' THEN 1 END) AS upi_orders
FROM orders
GROUP BY order_date
ORDER BY order_date;
This is a pivot done in plain SQL. Rows (one per payment mode) become columns. No special PIVOT syntax needed, and it works in PostgreSQL, MySQL, SQL Server, and BigQuery alike.
Example: Monthly Sales by City
A classic interview and dashboard task - sales per city, one column per month:
SELECT
city,
SUM(CASE WHEN MONTH(order_date) = 1 THEN order_amount ELSE 0 END) AS jan_sales,
SUM(CASE WHEN MONTH(order_date) = 2 THEN order_amount ELSE 0 END) AS feb_sales,
SUM(CASE WHEN MONTH(order_date) = 3 THEN order_amount ELSE 0 END) AS mar_sales
FROM orders
WHERE YEAR(order_date) = 2025
GROUP BY city;
A kirana owner could read this instantly: Mumbai did ₹4.2L in Jan, Pune ₹1.1L, and so on.
Computing Rates and Percentages
Combine conditional COUNT with COUNT(*) to get conversion or success rates. Use AVG of a 0/1 flag as a neat shortcut:
SELECT
delivery_partner,
COUNT(*) AS total_deliveries,
AVG(CASE WHEN status = 'Delivered' THEN 1.0 ELSE 0 END) AS success_rate
FROM deliveries
GROUP BY delivery_partner;
AVG of a 1/0 column equals the fraction of 1s - your success rate, directly. Note the 1.0 (not 1) to force floating-point division and avoid integer truncation, a trap in MySQL and SQL Server.
Common Pitfalls
These bugs quietly produce wrong numbers, which is worse than an error.
- Forgetting ELSE in SUM.
SUM(CASE WHEN x THEN amount END)works becauseSUMignoresNULL, but mixing this habit with arithmetic later can surprise you. Being explicit withELSE 0is safer and more readable. - Overlapping conditions. If two
WHENbranches can both be true, only the first fires. Order them deliberately. - Integer division.
COUNT(...)/COUNT(*)returns0in many engines because both are integers. Multiply by1.0orCASTto decimal. - Counting with ELSE 0 in COUNT.
COUNT(CASE WHEN x THEN 1 ELSE 0 END)counts every row, because0is notNULL. Drop theELSEwhen usingCOUNT, or switch toSUM. - NULLs in the test column. A row where
payment_mode IS NULLmatches noWHEN, so it lands inELSE. Decide consciously whether that is correct.
Best Practices
- Prefer conditional aggregation over multiple round-trips to the database - one scan instead of many.
- Alias every computed column clearly (
upi_revenue, notcol1) so dashboards and downstream code stay readable. - For very wide pivots (12 months, 30 cities), generate the SQL programmatically rather than hand-typing each branch.
- Keep the
CASElogic in SQL when it is reporting logic; push it to the BI layer (Power BI, Looker) only when it is presentation logic.
CASE plus aggregation is one of the highest-leverage skills in analyst SQL. Master the SUM(CASE ... END) pattern and you will reach for it in nearly every reporting query you write.
Related: SQL + Power BI Challenge for Data Analysts · Practise SQL problems
Don't just read. Prove your skill on DevWithData.
Shashikant
· Founder, DevWithDataData professional and Power BI instructor. Building DevWithData to help analysts prove their skills, not just collect certificates.
Reading is not enough. Prove your skill.
DevWithData measures your actual ability with the Data Readiness Index. Stop reading — start practicing.
Continue Learning
AI Tools for Data Analysts in 2026 (ChatGPT, Claude, Copilot)
AI tools like ChatGPT, Claude, and Copilot can write SQL, explain DAX, and speed up EDA, but only if you use them responsibly. This guide shows Indian data analysts exactly how to use AI in 2026: the right prompts for SQL and Python, where it helps in exploratory analysis, the mistakes it makes, and the hard limits you must respect to keep your analysis correct and your job safe.
8 min readHow to Crack the Data Analyst Interview (End to End)
The full data analyst interview pipeline for India in 2026, stage by stage: resume screening, the SQL round, the case or take-home, and the behavioral interview. Learn what each stage tests, the exact SQL patterns that come up, how to structure a case answer, and how to talk about your projects so you convert interviews into offers at Indian product and service companies.
8 min readRecursive CTEs in SQL: Hierarchies & Sequences Made Simple
Recursive CTEs unlock SQL problems that normal queries can't touch: walking an org chart, exploding a category tree, or generating a full date spine for your reports. Learn the anchor + recursive pattern step by step with India-flavored examples like employee-manager hierarchies and a daily calendar for Flipkart sales, plus the termination tricks that stop infinite loops.
8 min read