Popular Searches
Popular Course Categories
Popular Courses

Combining Aggregate Functions with Conditional Logic

Combining Aggregate Functions with Conditional Logic

Aggregate Functions and Data Grouping

Combining Aggregate Functions with Conditional Logic in MySQL

Course: MySQL Training Course

Topic: Combining Aggregate Functions with Conditional Logic

Course Link: MySQL Training Course

Demo Link: Register for a Free Course Demo


1. Introduction to Aggregate Functions with Conditional Logic

In MySQL, aggregate functions perform calculations on multiple rows and return a single result or one result for each group. Common aggregate functions include SUM(), COUNT(), AVG(), MIN(), and MAX().

Conditional logic allows a query to make decisions based on specified conditions. MySQL provides expressions such as CASE and IF() to return different values depending on whether a condition is satisfied.

Combining aggregate functions with conditional logic is known as conditional aggregation. It helps calculate totals, counts, averages, and other summaries for selected categories of records without requiring a separate query for every condition.

For example, a sales report can display total sales, completed sales, pending sales, and cancelled sales in a single query. Similarly, an employee report can calculate the number of employees in different salary ranges.

1.1 Learning Objectives

  • Understand aggregate functions and conditional expressions in MySQL.
  • Learn how to use CASE inside SUM(), COUNT(), and AVG().
  • Use IF() for simple conditional calculations.
  • Combine conditional aggregation with GROUP BY and HAVING.
  • Generate reports that summarize multiple categories in one query.
  • Handle NULL values and avoid common conditional aggregation errors.

2. Understanding Aggregate Functions in MySQL

Aggregate functions process a collection of values and return a summary. They are frequently used in reports, dashboards, financial calculations, and business analysis.

Function Purpose Example
SUM() Adds numeric values. SUM(amount)
COUNT() Counts rows or non-NULL values. COUNT(*)
AVG() Calculates the average of non-NULL values. AVG(salary)
MIN() Returns the smallest value. MIN(price)
MAX() Returns the largest value. MAX(price)

2.1 Example: Using Aggregate Functions

Consider a table named orders containing order amounts and statuses.

SELECT
    COUNT(*) AS total_orders,
    SUM(amount) AS total_sales,
    AVG(amount) AS average_order_amount,
    MIN(amount) AS smallest_order,
    MAX(amount) AS largest_order
FROM orders;

This query returns the number of orders, total sales, average order amount, smallest order amount, and largest order amount for the rows included in the query.

3. Understanding Conditional Logic

Conditional logic evaluates a condition and returns a value depending on the result. In MySQL, CASE and IF() are commonly used inside aggregate functions.

3.1 The CASE Expression

The CASE expression evaluates conditions and returns the result associated with the first matching condition.

Syntax:

CASE
    WHEN condition1 THEN result1
    WHEN condition2 THEN result2
    ELSE default_result
END

If no condition matches and an ELSE branch is omitted, the expression returns NULL.

Example:

SELECT
    order_id,
    amount,
    CASE
        WHEN amount >= 10000 THEN 'High Value'
        WHEN amount >= 5000 THEN 'Medium Value'
        ELSE 'Low Value'
    END AS order_category
FROM orders;

This query classifies each order based on its amount. The same conditional expression can also be placed inside an aggregate function to summarize particular categories.

3.2 The IF() Function

The MySQL IF() function returns one value when a condition is true and another when it is false.

Syntax:

IF(condition, value_if_true, value_if_false)

Example:

SELECT
    order_id,
    IF(amount >= 5000, 'Large Order', 'Small Order') AS order_type
FROM orders;

IF() is convenient for simple two-outcome conditions. For multiple categories or more complex conditions, CASE is generally easier to read.

4. What Is Conditional Aggregation?

Conditional aggregation combines an aggregate function with a conditional expression. The condition determines which values contribute to the calculation.

For example, the expression below calculates sales only for completed orders:

SELECT
    SUM(
        CASE
            WHEN status = 'Completed' THEN amount
            ELSE 0
        END
    ) AS completed_sales
FROM orders;

The CASE expression returns the order amount when the status is Completed. For other orders, it returns zero. The SUM() function adds the resulting values.

4.1 General Syntax

SELECT
    aggregate_function(
        CASE
            WHEN condition THEN expression
            ELSE default_value
        END
    ) AS result
FROM table_name;

4.2 Why Conditional Aggregation Is Useful

  • Calculates multiple conditional totals in a single query.
  • Reduces the need for separate queries for each category.
  • Creates useful summary reports for business analysis.
  • Works with grouped data, such as sales by region or employees by department.
  • Can transform category values into separate report columns.
  • Makes it easier to compare completed, pending, and cancelled transactions.

5. Creating a Sample Table for Practice

For the examples in these notes, create a sample table called orders.

CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    customer_name VARCHAR(100),
    region VARCHAR(50),
    amount DECIMAL(10,2),
    status VARCHAR(30)
);

5.1 Inserting Sample Records

INSERT INTO orders
(order_id, customer_name, region, amount, status)
VALUES
(1, 'Amit', 'North', 12000.00, 'Completed'),
(2, 'Priya', 'South', 7500.00, 'Pending'),
(3, 'Rahul', 'North', 4500.00, 'Completed'),
(4, 'Neha', 'West', 9000.00, 'Cancelled'),
(5, 'Vikas', 'South', 15000.00, 'Completed'),
(6, 'Sneha', 'West', 3000.00, 'Pending'),
(7, 'Arjun', 'North', 8000.00, 'Pending'),
(8, 'Meera', 'South', 6000.00, 'Cancelled'),
(9, 'Karan', 'West', 11000.00, 'Completed'),
(10, 'Isha', 'North', 5000.00, 'Cancelled');

These records contain different order amounts, regions, and statuses. They can be used to practice counting records, calculating conditional totals, comparing categories, and generating grouped reports.

5.2 Viewing the Sample Data

SELECT *
FROM orders
ORDER BY order_id;

6. Combining SUM() with Conditional Logic

The SUM() function adds numeric values. When combined with CASE, it can add values only when a particular condition is satisfied.

6.1 Calculating Sales for Completed Orders

SELECT
    SUM(
        CASE
            WHEN status = 'Completed' THEN amount
            ELSE 0
        END
    ) AS completed_sales
FROM orders;

Expected result: 42,500.00

Only the amounts for Completed orders are added: 12,000 + 4,500 + 15,000 + 11,000.

6.2 Calculating Sales for Multiple Statuses

Several conditional totals can be calculated in one query by using multiple SUM(CASE ...) expressions.

SELECT
    SUM(amount) AS total_sales,
    SUM(CASE
        WHEN status = 'Completed' THEN amount
        ELSE 0
    END) AS completed_sales,
    SUM(CASE
        WHEN status = 'Pending' THEN amount
        ELSE 0
    END) AS pending_sales,
    SUM(CASE
        WHEN status = 'Cancelled' THEN amount
        ELSE 0
    END) AS cancelled_sales
FROM orders;

Expected result:

Total Sales Completed Sales Pending Sales Cancelled Sales
81,000.00 42,500.00 18,500.00 20,000.00

This report presents all three status totals alongside total sales without requiring three separate queries.

6.3 Calculating Sales Above a Threshold

Conditional aggregation can also select values using numeric comparisons.

SELECT
    SUM(CASE
        WHEN amount >= 10000 THEN amount
        ELSE 0
    END) AS high_value_sales
FROM orders;

This query adds only amounts that are at least 10,000.00. The result is 38,000.00.

7. Combining COUNT() with Conditional Logic

The COUNT() function counts rows or non-NULL expressions. Combining it with CASE allows you to count records that satisfy a condition.

7.1 Counting Completed Orders

SELECT
    COUNT(
        CASE
            WHEN status = 'Completed' THEN 1
        END
    ) AS completed_orders
FROM orders;

Expected result: 4

When the condition is true, CASE returns 1. Otherwise, it returns NULL because no ELSE branch is provided. Since COUNT(expression) ignores NULL values, only completed orders are counted.

7.2 Counting Orders by Status

SELECT
    COUNT(*) AS total_orders,
    COUNT(CASE
        WHEN status = 'Completed' THEN 1
    END) AS completed_orders,
    COUNT(CASE
        WHEN status = 'Pending' THEN 1
    END) AS pending_orders,
    COUNT(CASE
        WHEN status = 'Cancelled' THEN 1
    END) AS cancelled_orders
FROM orders;

Expected result:

Total Orders Completed Pending Cancelled
10 4 3 3

7.3 Alternative Using SUM()

Another common technique is to return 1 for matching records and 0 for non-matching records, then add the results.

SELECT
    SUM(CASE
        WHEN status = 'Completed' THEN 1
        ELSE 0
    END) AS completed_orders
FROM orders;

Both methods can produce the same count. With COUNT(CASE ...), omitting ELSE is important when you want non-matching records to become NULL and not be counted.

8. Combining AVG() with Conditional Logic

The AVG() function calculates the average of non-NULL values. When combined with CASE, it can calculate the average for records that meet a condition.

8.1 Average Amount for Completed Orders

SELECT
    AVG(CASE
        WHEN status = 'Completed' THEN amount
    END) AS average_completed_order
FROM orders;

Expected result: 10,625.00

Only completed order amounts are returned by the conditional expression. Other rows produce NULL and are ignored by AVG().

8.2 Comparing Average Amounts by Status

SELECT
    AVG(CASE
        WHEN status = 'Completed' THEN amount
    END) AS avg_completed,
    AVG(CASE
        WHEN status = 'Pending' THEN amount
    END) AS avg_pending,
    AVG(CASE
        WHEN status = 'Cancelled' THEN amount
    END) AS avg_cancelled
FROM orders;

This query returns the average order amount for each status in separate columns.

Status Calculation Average Amount
Completed (12,000 + 4,500 + 15,000 + 11,000) / 4 10,625.00
Pending (7,500 + 3,000 + 8,000) / 3 6,166.67
Cancelled (9,000 + 6,000 + 5,000) / 3 6,666.67

8.3 Understanding NULL in Conditional Averages

For conditional averages, omitting ELSE 0 is often intentional. It ensures that non-matching rows are excluded from both the sum and the count used to calculate the average.

-- Average of completed orders only
SELECT AVG(
    CASE
        WHEN status = 'Completed' THEN amount
    END
) AS completed_average
FROM orders;

If you use ELSE 0, the zeros from non-matching rows are included in the average and may lower the result. Choose the expression that matches the intended business calculation.

9. Combining MIN() and MAX() with Conditional Logic

The MIN() and MAX() functions can identify the smallest and largest values among records that satisfy a condition.

9.1 Minimum Completed Order

SELECT
    MIN(CASE
        WHEN status = 'Completed' THEN amount
    END) AS smallest_completed_order
FROM orders;

Expected result: 4,500.00

9.2 Maximum Completed Order

SELECT
    MAX(CASE
        WHEN status = 'Completed' THEN amount
    END) AS largest_completed_order
FROM orders;

Expected result: 15,000.00

9.3 Comparing Minimum and Maximum by Status

SELECT
    MIN(CASE
        WHEN status = 'Completed' THEN amount
    END) AS min_completed,
    MAX(CASE
        WHEN status = 'Completed' THEN amount
    END) AS max_completed,
    MIN(CASE
        WHEN status = 'Pending' THEN amount
    END) AS min_pending,
    MAX(CASE
        WHEN status = 'Pending' THEN amount
    END) AS max_pending
FROM orders;

This approach can help identify the range of order values for different categories in a single report.

10. Using IF() Inside Aggregate Functions

MySQL's IF() function can be used inside aggregate functions for straightforward conditions. It is an alternative to some CASE expressions.

10.1 Conditional SUM() with IF()

SELECT
    SUM(IF(status = 'Completed', amount, 0)) AS completed_sales
FROM orders;

This expression adds the order amount when the status is Completed and adds zero for other statuses.

10.2 Conditional COUNT() with IF()

SELECT
    COUNT(IF(status = 'Completed', 1, NULL)) AS completed_orders
FROM orders;

The expression returns 1 for completed orders and NULL for other records. COUNT() counts the non-NULL results.

10.3 CASE Versus IF()

Feature CASE IF()
Conditions Supports multiple conditions. Supports one condition with two outcomes.
Readability Suitable for complex business rules. Compact for simple true/false logic.
Example SUM(CASE WHEN status='Completed' THEN amount ELSE 0 END) SUM(IF(status='Completed', amount, 0))
Recommendation Prefer for multiple categories or complex rules. Useful for short, simple conditions.

11. Combining Conditional Aggregation with GROUP BY

The GROUP BY clause divides records into groups. Aggregate functions then calculate results for each group. Conditional aggregation can calculate several metrics within every group.

11.1 Sales by Region and Status

SELECT
    region,
    SUM(amount) AS total_sales,
    SUM(CASE
        WHEN status = 'Completed' THEN amount
        ELSE 0
    END) AS completed_sales,
    SUM(CASE
        WHEN status = 'Pending' THEN amount
        ELSE 0
    END) AS pending_sales,
    SUM(CASE
        WHEN status = 'Cancelled' THEN amount
        ELSE 0
    END) AS cancelled_sales
FROM orders
GROUP BY region
ORDER BY region;

This query groups records by region and calculates total sales and status-specific sales for each region.

11.2 Counting Statuses by Region

SELECT
    region,
    COUNT(*) AS total_orders,
    COUNT(CASE
        WHEN status = 'Completed' THEN 1
    END) AS completed_orders,
    COUNT(CASE
        WHEN status = 'Pending' THEN 1
    END) AS pending_orders,
    COUNT(CASE
        WHEN status = 'Cancelled' THEN 1
    END) AS cancelled_orders
FROM orders
GROUP BY region
ORDER BY region;

This query produces a regional order summary with counts for each status.

11.3 Why GROUP BY Matters

  • Without GROUP BY, the query produces one summary row for all selected records.
  • With GROUP BY region, the query produces one summary row per region.
  • Conditional expressions determine which rows contribute to each metric.
  • Multiple conditional aggregates can be calculated in the same grouped query.

12. Combining Conditional Aggregation with HAVING

The HAVING clause filters groups after aggregation. It is useful when you want to display only groups whose conditional totals or counts meet a requirement.

12.1 Regions with Completed Sales Above 10,000

SELECT
    region,
    SUM(CASE
        WHEN status = 'Completed' THEN amount
        ELSE 0
    END) AS completed_sales
FROM orders
GROUP BY region
HAVING SUM(CASE
    WHEN status = 'Completed' THEN amount
    ELSE 0
END) > 10000;

Only regions whose completed sales exceed 10,000 are returned.

12.2 Regions with at Least Two Completed Orders

SELECT
    region,
    COUNT(CASE
        WHEN status = 'Completed' THEN 1
    END) AS completed_orders
FROM orders
GROUP BY region
HAVING COUNT(CASE
    WHEN status = 'Completed' THEN 1
END) >= 2;

This query returns regions with at least two completed orders.

12.3 WHERE Versus HAVING

Clause Purpose Example
WHERE Filters individual rows before grouping. WHERE region = 'North'
HAVING Filters grouped results after aggregation. HAVING SUM(amount) > 10000

13. Conditional Aggregation for Employee Reports

Conditional aggregation is not limited to sales. It can also summarize employee information, attendance, salaries, performance ratings, and department-level statistics.

13.1 Create an Employee Table

CREATE TABLE employees (
    employee_id INT PRIMARY KEY,
    employee_name VARCHAR(100),
    department VARCHAR(50),
    salary DECIMAL(10,2),
    employment_status VARCHAR(20)
);

13.2 Sample Employee Records

INSERT INTO employees
(employee_id, employee_name, department, salary, employment_status)
VALUES
(1, 'Aarav', 'IT', 60000, 'Active'),
(2, 'Diya', 'HR', 45000, 'Active'),
(3, 'Kabir', 'IT', 75000, 'Active'),
(4, 'Anaya', 'Sales', 50000, 'Inactive'),
(5, 'Ishaan', 'HR', 40000, 'Inactive'),
(6, 'Riya', 'Sales', 65000, 'Active');

13.3 Counting Active and Inactive Employees

SELECT
    COUNT(*) AS total_employees,
    COUNT(CASE
        WHEN employment_status = 'Active' THEN 1
    END) AS active_employees,
    COUNT(CASE
        WHEN employment_status = 'Inactive' THEN 1
    END) AS inactive_employees
FROM employees;

13.4 Calculating Active Employee Salaries by Department

SELECT
    department,
    SUM(salary) AS total_department_salary,
    SUM(CASE
        WHEN employment_status = 'Active' THEN salary
        ELSE 0
    END) AS active_salary_total,
    AVG(CASE
        WHEN employment_status = 'Active' THEN salary
    END) AS active_average_salary
FROM employees
GROUP BY department
ORDER BY department;

This report shows the total salary for each department, the salary total for active employees, and the average salary among active employees.

14. Using Conditional Aggregation for Financial Reports

Financial reports often require several related calculations, such as income, expenses, refunds, outstanding payments, and net totals. Conditional aggregation can place these metrics into one result set.

14.1 Example: Transactions Table

CREATE TABLE transactions (
    transaction_id INT PRIMARY KEY,
    transaction_type VARCHAR(20),
    amount DECIMAL(10,2)
);

14.2 Calculate Income, Expenses, and Refunds

SELECT
    SUM(CASE
        WHEN transaction_type = 'Income' THEN amount
        ELSE 0
    END) AS total_income,
    SUM(CASE
        WHEN transaction_type = 'Expense' THEN amount
        ELSE 0
    END) AS total_expenses,
    SUM(CASE
        WHEN transaction_type = 'Refund' THEN amount
        ELSE 0
    END) AS total_refunds
FROM transactions;

The query creates separate totals for each transaction type. The correct interpretation of the final net amount depends on how the business records refunds and expenses, so the accounting rules should be clearly defined before calculating profit or cash flow.

15. Creating a Summary Report with Multiple Aggregate Functions

A single query can combine COUNT(), SUM(), AVG(), MIN(), and MAX() with conditional logic to produce a detailed summary.

SELECT
    COUNT(*) AS total_orders,
    SUM(amount) AS total_sales,
    AVG(amount) AS average_order_amount,
    MIN(amount) AS minimum_order_amount,
    MAX(amount) AS maximum_order_amount,
    COUNT(CASE
        WHEN status = 'Completed' THEN 1
    END) AS completed_order_count,
    SUM(CASE
        WHEN status = 'Completed' THEN amount
        ELSE 0
    END) AS completed_sales,
    AVG(CASE
        WHEN status = 'Completed' THEN amount
    END) AS average_completed_order
FROM orders;

This report combines overall metrics with metrics specific to completed orders. It is useful for management dashboards and routine business reporting.

16. Calculating Percentages with Conditional Aggregation

Conditional aggregation can calculate the proportion of records or sales belonging to a category. The numerator represents the selected category, while the denominator represents the total.

16.1 Percentage of Completed Orders

SELECT
    COUNT(*) AS total_orders,
    COUNT(CASE
        WHEN status = 'Completed' THEN 1
    END) AS completed_orders,
    ROUND(
        100.0 * COUNT(CASE
            WHEN status = 'Completed' THEN 1
        END) / NULLIF(COUNT(*), 0),
        2
    ) AS completed_order_percentage
FROM orders;

The query calculates the percentage of orders that are completed. NULLIF(COUNT(*), 0) prevents division by zero if the table contains no rows.

16.2 Percentage of Completed Sales

SELECT
    SUM(amount) AS total_sales,
    SUM(CASE
        WHEN status = 'Completed' THEN amount
        ELSE 0
    END) AS completed_sales,
    ROUND(
        100.0 * SUM(CASE
            WHEN status = 'Completed' THEN amount
            ELSE 0
        END) / NULLIF(SUM(amount), 0),
        2
    ) AS completed_sales_percentage
FROM orders;

This calculation measures completed sales as a percentage of total sales. If amounts can be NULL or negative in your real dataset, define the business rules for those values before interpreting the percentage.

17. Conditional Aggregation and NULL Values

NULL represents a missing or unknown value. Aggregate functions do not all handle NULL in the same way, so conditional expressions must be designed carefully.

17.1 How Aggregate Functions Handle NULL

Expression NULL Behavior
COUNT(*) Counts rows, even if some column values are NULL.
COUNT(column_name) Counts non-NULL values in the specified column.
SUM(column_name) Ignores NULL values; returns NULL if there are no non-NULL inputs.
AVG(column_name) Ignores NULL values when calculating the average.
MIN() and MAX() Ignore NULL values when finding the minimum or maximum.

17.2 Handling NULL in a Conditional SUM()

SELECT
    COALESCE(
        SUM(CASE
            WHEN status = 'Completed' THEN amount
            ELSE 0
        END),
        0
    ) AS completed_sales
FROM orders;

COALESCE() returns the first non-NULL expression. It can be used to display zero when the aggregate result is NULL. However, if a matching order has a NULL amount, that amount is still not a known numeric value; decide whether it should be excluded, treated as zero, or handled separately.

17.3 Handling NULL Status Values

SELECT
    COUNT(*) AS total_orders,
    COUNT(CASE
        WHEN status IS NULL THEN 1
    END) AS orders_without_status
FROM orders;

Use IS NULL to test for missing values. A comparison such as status = NULL does not correctly test for NULL.

18. Common Mistakes and Troubleshooting

18.1 Using COUNT() with ELSE 0 Incorrectly

Incorrect for counting only completed orders:

SELECT
    COUNT(CASE
        WHEN status = 'Completed' THEN 1
        ELSE 0
    END) AS completed_orders
FROM orders;

This counts every row because both 1 and 0 are non-NULL values. Use the following version instead:

SELECT
    COUNT(CASE
        WHEN status = 'Completed' THEN 1
    END) AS completed_orders
FROM orders;

Alternatively, use SUM(CASE WHEN condition THEN 1 ELSE 0 END) to count matching rows.

18.2 Using ELSE 0 in an Average

If the objective is to average only completed orders, using ELSE 0 incorrectly includes non-completed rows as zeros.

-- Average only the matching rows
SELECT AVG(
    CASE
        WHEN status = 'Completed' THEN amount
    END
) AS average_completed_amount
FROM orders;

18.3 Forgetting GROUP BY

If a report requires one result per region or department, include the appropriate GROUP BY clause. Without it, aggregate functions summarize the selected rows as a whole.

18.4 Using the Wrong Condition

Check spelling, capitalization behavior under the column's collation, numeric thresholds, and category values. For example, a condition for 'Complete' will not match rows stored as 'Completed'.

18.5 Mixing Row Filters and Group Filters

Use WHERE to filter individual records before aggregation and HAVING to filter grouped results. Choosing the wrong clause can change the report's meaning.

18.6 Ignoring NULL Values

Decide how missing amounts, statuses, and other values should be handled. NULL is not automatically equivalent to zero or an empty string.

18.7 Repeating Complex Conditions

When the same condition appears in many expressions, check that every expression uses the intended rule. For complicated reports, consider using a common table expression or derived table to make the logic easier to maintain.

19. Best Practices for Conditional Aggregation

  • Use descriptive aliases such as completed_sales and pending_orders.
  • Use CASE when conditions involve several categories or business rules.
  • Use IF() for simple two-outcome expressions when it improves readability.
  • Use COUNT(CASE WHEN condition THEN 1 END) to count matching rows.
  • Use SUM(CASE WHEN condition THEN amount ELSE 0 END) to total values conditionally.
  • For conditional averages, omit ELSE 0 when non-matching rows should not affect the average.
  • Use GROUP BY when results are required separately for regions, departments, months, or categories.
  • Use HAVING to filter groups based on aggregate results.
  • Use NULLIF() to protect percentage calculations from division by zero.
  • Test queries with known sample data and verify totals independently.
  • Use suitable indexes for filtering and joining when working with large datasets, and examine execution plans when performance matters.
  • Keep business definitions consistent, especially for refunds, cancelled transactions, missing values, and revenue totals.

20. Practice Exercises

Exercise 1: Count Completed Orders

Write a query to count only orders whose status is Completed.

SELECT
    COUNT(CASE
        WHEN status = 'Completed' THEN 1
    END) AS completed_orders
FROM orders;

Exercise 2: Calculate Pending Sales

Write a query to calculate the total amount of pending orders.

SELECT
    SUM(CASE
        WHEN status = 'Pending' THEN amount
        ELSE 0
    END) AS pending_sales
FROM orders;

Exercise 3: Calculate Average Cancelled Order Amount

Write a query to calculate the average amount for cancelled orders only.

SELECT
    AVG(CASE
        WHEN status = 'Cancelled' THEN amount
    END) AS average_cancelled_amount
FROM orders;

Exercise 4: Summarize Sales by Region

Display total sales and completed sales for each region.

SELECT
    region,
    SUM(amount) AS total_sales,
    SUM(CASE
        WHEN status = 'Completed' THEN amount
        ELSE 0
    END) AS completed_sales
FROM orders
GROUP BY region;

Exercise 5: Calculate the Completed Order Percentage

Calculate the percentage of orders that have been completed.

SELECT
    ROUND(
        100.0 * COUNT(CASE
            WHEN status = 'Completed' THEN 1
        END) / NULLIF(COUNT(*), 0),
        2
    ) AS completed_percentage
FROM orders;

Exercise 6: Find the Largest Completed Order

Display the largest amount among completed orders.

SELECT
    MAX(CASE
        WHEN status = 'Completed' THEN amount
    END) AS largest_completed_order
FROM orders;

21. Mini Project: Order Performance Summary

Project Objective: Create a MySQL report that summarizes order performance across regions, including order counts, total sales, completed sales, pending sales, cancelled sales, and the completed-order percentage.

21.1 Project Requirements

  • Display one row for each region.
  • Calculate the total number of orders.
  • Count completed, pending, and cancelled orders separately.
  • Calculate total sales and sales for each status.
  • Calculate the percentage of completed orders within each region.
  • Sort the report by total sales in descending order.

21.2 Project Solution

SELECT
    region,
    COUNT(*) AS total_orders,
    COUNT(CASE
        WHEN status = 'Completed' THEN 1
    END) AS completed_orders,
    COUNT(CASE
        WHEN status = 'Pending' THEN 1
    END) AS pending_orders,
    COUNT(CASE
        WHEN status = 'Cancelled' THEN 1
    END) AS cancelled_orders,
    SUM(amount) AS total_sales,
    SUM(CASE
        WHEN status = 'Completed' THEN amount
        ELSE 0
    END) AS completed_sales,
    SUM(CASE
        WHEN status = 'Pending' THEN amount
        ELSE 0
    END) AS pending_sales,
    SUM(CASE
        WHEN status = 'Cancelled' THEN amount
        ELSE 0
    END) AS cancelled_sales,
    ROUND(
        100.0 * COUNT(CASE
            WHEN status = 'Completed' THEN 1
        END) / NULLIF(COUNT(*), 0),
        2
    ) AS completed_order_percentage
FROM orders
GROUP BY region
ORDER BY total_sales DESC;

21.3 Project Learning Outcomes

  • Combine several aggregate functions in one query.
  • Apply conditions inside aggregate expressions.
  • Generate grouped business reports.
  • Calculate percentages safely.
  • Interpret summary results for decision-making.

22. Interview Questions and Answers

Q1. What is conditional aggregation in MySQL?

Answer: Conditional aggregation combines aggregate functions such as SUM(), COUNT(), or AVG() with expressions such as CASE or IF() to calculate summaries for selected records.

Q2. Why combine CASE with SUM()?

Answer: It allows a query to add values only when a condition is satisfied, such as calculating total revenue from completed orders.

Q3. How do you count rows that meet a condition?

Answer: Use COUNT(CASE WHEN condition THEN 1 END) or SUM(CASE WHEN condition THEN 1 ELSE 0 END).

Q4. Why should ELSE 0 be avoided in some COUNT(CASE) expressions?

Answer: Because COUNT() counts every non-NULL result, including zero. Omitting ELSE makes non-matching rows return NULL, which is not counted.

Q5. When should ELSE 0 be used with SUM()?

Answer: It is commonly used when non-matching rows should contribute zero to a conditional total.

Q6. Why might ELSE 0 be inappropriate inside AVG()?

Answer: Non-matching rows would contribute zero to the average and could lower the result. Omit the ELSE branch when only matching values should be averaged.

Q7. What is the difference between CASE and IF()?

Answer: CASE supports multiple conditions and is useful for complex rules. IF() is a compact function for a single condition with two possible outcomes.

Q8. Can conditional aggregation be used with GROUP BY?

Answer: Yes. It can calculate conditional totals and counts separately for each group, such as each department or region.

Q9. What is the difference between WHERE and HAVING?

Answer: WHERE filters rows before grouping, while HAVING filters groups after aggregate calculations.

Q10. How can you calculate the percentage of completed orders?

Answer: Divide the conditional count of completed orders by the total row count, multiply by 100, and use NULLIF() to avoid division by zero.

Q11. What happens when SUM() receives only NULL values?

Answer: It returns NULL when there are no non-NULL input values. COALESCE() can be used to provide a default result when appropriate.

Q12. Can multiple conditional aggregates appear in one SELECT statement?

Answer: Yes. A single query can include multiple conditional counts, sums, averages, minimums, and maximums.

23. Quick Revision Checklist

  • Aggregate functions summarize values across multiple rows.
  • CASE evaluates conditions and returns the appropriate result.
  • IF() handles a simple condition with two outcomes.
  • SUM(CASE ...) calculates conditional totals.
  • COUNT(CASE WHEN condition THEN 1 END) counts matching records.
  • AVG(CASE ...) calculates an average for matching records.
  • MIN(CASE ...) and MAX(CASE ...) find conditional minimums and maximums.
  • GROUP BY produces a summary for each group.
  • HAVING filters groups based on aggregate conditions.
  • NULL handling can change aggregate results.
  • NULLIF() can prevent division by zero in percentage calculations.
  • Always verify whether non-matching records should contribute zero or be excluded.

24. Conclusion

Combining aggregate functions with conditional logic is an important MySQL skill for building flexible and meaningful reports. By using CASE or IF() inside functions such as SUM(), COUNT(), AVG(), MIN(), and MAX(), you can calculate several category-specific metrics within one query.

When conditional aggregation is combined with GROUP BY, HAVING, and careful NULL handling, it becomes useful for sales analysis, employee reporting, financial summaries, and dashboard development. Practice these patterns with sample tables and verify each result to build confidence in writing accurate MySQL queries.

Continue Learning: Explore the MySQL Training Course to develop your SQL skills, and use the course demo registration page to learn more about the training.

whatsapp