SQL Clauses
SQL Clauses Interview with follow-up questions
1. Can you explain the difference between WHERE and HAVING clause in SQL?
Both clauses filter rows, but they operate at different stages of query execution.
WHERE filters individual rows before grouping. It applies to the raw rows in the table and cannot use aggregate functions.
SELECT department, COUNT(*) AS headcount
FROM employees
WHERE salary > 50000 -- filter rows BEFORE grouping
GROUP BY department;
HAVING filters groups after GROUP BY. It can reference aggregate functions.
SELECT department, COUNT(*) AS headcount
FROM employees
WHERE salary > 50000 -- filter rows before grouping
GROUP BY department
HAVING COUNT(*) > 5; -- filter GROUPS after aggregation
Why the distinction matters — logical execution order:
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY
HAVING executes after GROUP BY, so aggregate values exist at that point. WHERE executes before GROUP BY, so aggregates don't exist yet.
Common interview mistake: Writing WHERE COUNT(*) > 5 — this is invalid because COUNT(*) is not available at the WHERE stage. Use HAVING COUNT(*) > 5.
Can HAVING be used without GROUP BY? Yes — it applies to the entire result set as a single group:
SELECT AVG(salary) FROM employees HAVING AVG(salary) > 75000;
Performance tip: Filter as much as possible in WHERE before grouping, since reducing row count before GROUP BY is cheaper than filtering large groups in HAVING.
Follow-up 1
Can you provide an example where both WHERE and HAVING clause are used in a single SQL query?
Sure! Here's an example:
SELECT category, COUNT(*)
FROM products
WHERE price > 100
GROUP BY category
HAVING COUNT(*) > 5;
In this example, the WHERE clause filters the rows where the price is greater than 100. Then, the GROUP BY clause groups the rows by category. Finally, the HAVING clause filters the groups where the count of products is greater than 5.
Follow-up 2
What happens if we use WHERE clause with aggregate functions?
When we use the WHERE clause with aggregate functions, the condition specified in the WHERE clause is applied to individual rows before the aggregation is performed. Only the rows that satisfy the condition are included in the aggregation.
For example, consider the following query:
SELECT SUM(sales)
FROM orders
WHERE date > '2021-01-01';
In this query, the WHERE clause filters the rows where the date is greater than '2021-01-01'. Then, the SUM function is applied to the filtered rows to calculate the total sales.
Follow-up 3
Why can't we use HAVING clause without GROUP BY in SQL?
The HAVING clause is used to filter the results of a grouped query. It is applied after the GROUP BY clause, which means it operates on the groups created by the GROUP BY clause.
If we use the HAVING clause without the GROUP BY clause, there are no groups to filter, and the query would not make sense. The HAVING clause requires the GROUP BY clause to determine the groups on which the filtering should be applied.
In summary, the HAVING clause can only be used in conjunction with the GROUP BY clause in SQL.
2. What is the purpose of the GROUP BY clause in SQL?
GROUP BY collapses multiple rows sharing the same value(s) in the specified column(s) into a single summary row. It is almost always used with aggregate functions.
Basic usage:
SELECT department, COUNT(*) AS headcount, AVG(salary) AS avg_salary
FROM employees
GROUP BY department;
Each unique department value becomes one row in the result.
Multiple columns:
SELECT department, job_title, COUNT(*) AS count
FROM employees
GROUP BY department, job_title;
Groups by the combination of both columns.
With HAVING:
SELECT department, COUNT(*) AS headcount
FROM employees
GROUP BY department
HAVING COUNT(*) >= 10;
-- Only departments with 10 or more employees
Aggregate functions used with GROUP BY:
COUNT(*)— total rows in each groupSUM(col)— total of a numeric column per groupAVG(col)— average per groupMIN(col)/MAX(col)— extremes per groupSTRING_AGG(col, ',')/GROUP_CONCAT(col)— concatenate values per group
Important rule: Every column in SELECT must either be in the GROUP BY clause or be inside an aggregate function. Selecting a non-grouped, non-aggregated column is an error in standard SQL and PostgreSQL (MySQL/SQLite allow it but return an arbitrary value — a common source of bugs).
-- ERROR in PostgreSQL:
SELECT department, employee_name, COUNT(*) FROM employees GROUP BY department;
-- employee_name is neither in GROUP BY nor aggregated
Interview follow-up: What is the difference between COUNT(*) and COUNT(column)? COUNT(*) counts all rows; COUNT(column) counts only rows where the column is NOT NULL.
Follow-up 1
Can you provide an example of a SQL query using GROUP BY clause?
Sure! Here's an example:
SELECT department, COUNT(*) as total_employees
FROM employees
GROUP BY department;
This query groups the rows in the 'employees' table by the 'department' column and calculates the total number of employees in each department.
Follow-up 2
What is the difference between ORDER BY and GROUP BY clause?
The ORDER BY clause is used to sort the result set based on one or more columns, while the GROUP BY clause is used to group rows based on one or more columns. The ORDER BY clause affects the order in which the rows are displayed, while the GROUP BY clause affects the way the rows are grouped and the calculations performed on each group.
Follow-up 3
Can you use GROUP BY clause without an aggregate function?
No, the GROUP BY clause must be used with at least one aggregate function, such as COUNT, SUM, AVG, etc. The purpose of the GROUP BY clause is to perform calculations on each group of rows, and the aggregate function is used to specify the calculation to be performed.
3. How does the ORDER BY clause work in SQL?
ORDER BY sorts the final result set of a query in ascending or descending order based on one or more columns.
Syntax:
SELECT column1, column2
FROM table_name
ORDER BY column1 [ASC|DESC], column2 [ASC|DESC];
Key behaviors:
Default sort direction is ascending (ASC):
SELECT first_name, salary FROM employees ORDER BY salary; -- ASC (smallest first)
SELECT first_name, salary FROM employees ORDER BY salary DESC; -- largest first
Multiple sort columns (tiebreaker):
SELECT last_name, first_name, hire_date
FROM employees
ORDER BY last_name ASC, first_name ASC, hire_date DESC;
Sort by column position (fragile, avoid in production):
SELECT department, COUNT(*) FROM employees GROUP BY department ORDER BY 2 DESC;
-- ORDER BY 2 = second column = COUNT(*)
Sort using a SELECT alias (works because ORDER BY executes after SELECT):
SELECT department, COUNT(*) AS headcount
FROM employees
GROUP BY department
ORDER BY headcount DESC;
NULL sorting:
- In PostgreSQL and SQL Server: NULLs sort last in ASC, first in DESC
- PostgreSQL allows explicit control:
ORDER BY column NULLS FIRST/NULLS LAST - MySQL: NULLs sort first in ASC
Performance note: ORDER BY on large result sets without an index requires a sort operation (filesort in MySQL). If you always query in a specific order, an index on that column can eliminate the sort entirely.
Without LIMIT: ORDER BY alone does not limit rows — it only affects their sequence.
Follow-up 1
Can you provide an example of a SQL query using ORDER BY clause?
Sure! Here's an example of a SQL query using the ORDER BY clause:
SELECT name, age FROM employees ORDER BY age DESC;
This query selects the 'name' and 'age' columns from the 'employees' table and sorts the result set in descending order based on the 'age' column. The result will be a list of employee names and ages, ordered from oldest to youngest.
Follow-up 2
What is the default sorting order of the ORDER BY clause?
The default sorting order of the ORDER BY clause is ascending (ASC). If you don't specify the sorting order explicitly, the result set will be sorted in ascending order based on the specified column(s).
Follow-up 3
Can you use ORDER BY clause in a subquery?
Yes, you can use the ORDER BY clause in a subquery. The ORDER BY clause can be used in the subquery itself or in the outer query that references the subquery. When using the ORDER BY clause in a subquery, it is important to note that the ordering of the result set in the subquery does not affect the ordering of the outer query. The ORDER BY clause in the outer query will determine the final ordering of the result set.
4. What is the use of the DISTINCT clause in SQL?
DISTINCT eliminates duplicate rows from a query's result set, returning only unique combinations of the selected columns.
Basic usage:
-- Without DISTINCT: may return duplicate department values
SELECT department FROM employees;
-- With DISTINCT: each department appears once
SELECT DISTINCT department FROM employees;
Multi-column DISTINCT — uniqueness is evaluated across all selected columns together:
SELECT DISTINCT department, job_title FROM employees;
-- Returns each unique (department, job_title) combination
Common use cases:
Find unique values in a column:
SELECT DISTINCT country FROM customers ORDER BY country;
Count unique values (COUNT DISTINCT):
SELECT COUNT(DISTINCT customer_id) AS unique_customers FROM orders;
Remove duplicates from a UNION result — UNION already does this; UNION ALL with DISTINCT is redundant.
Performance implications:
DISTINCTrequires sorting or hashing the result to identify duplicates — this adds overhead- On large result sets,
DISTINCTcan be expensive - If you find yourself using
DISTINCTto remove duplicates from a JOIN result, it may indicate a schema issue or a JOIN that produces unintended Cartesian pairs
DISTINCT vs GROUP BY:
Both can produce unique values, but GROUP BY is used when you also need aggregates. For simply deduplicating output, DISTINCT is clearer. Some query planners generate identical execution plans for both.
Interview note: If an interviewer asks "when would you NOT use DISTINCT?" — answer: when you need duplicates to count correctly (e.g., a sales total should include each sale, not just unique sales).
Follow-up 1
Can you provide an example of a SQL query using DISTINCT clause?
Sure! Here's an example:
SELECT DISTINCT column_name FROM table_name;
This query will retrieve all the unique values from the specified column in the table.
Follow-up 2
What is the difference between DISTINCT and UNIQUE in SQL?
In SQL, the DISTINCT keyword is used in the SELECT statement to retrieve unique values from a column or a combination of columns in a table. On the other hand, the UNIQUE constraint is used when creating a table to ensure that the values in a column or a combination of columns are unique.
While DISTINCT is used in queries to filter the result set, UNIQUE is used to define the data integrity rules for a table.
Follow-up 3
Can you use DISTINCT clause with multiple columns?
Yes, the DISTINCT clause can be used with multiple columns in a SQL query. Here's an example:
SELECT DISTINCT column1, column2 FROM table_name;
This query will retrieve all the unique combinations of values from the specified columns in the table.
5. Can you explain the concept of the JOIN clause in SQL?
A JOIN clause combines rows from two or more tables based on a related column between them, allowing you to retrieve data spread across multiple tables in a single query.
Basic syntax:
SELECT a.column1, b.column2
FROM table_a a
JOIN table_b b ON a.key_column = b.key_column;
Types of JOINs:
INNER JOIN (default) — returns rows where the join condition is met in both tables:
SELECT e.name, d.department_name
FROM employees e
INNER JOIN departments d ON e.department_id = d.id;
-- Only employees who have a matching department
LEFT (OUTER) JOIN — all rows from the left table + matching rows from the right (NULLs for no match):
SELECT c.name, o.order_id
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id;
-- All customers, even those with no orders
RIGHT (OUTER) JOIN — all rows from the right table + matching from the left (less common; rewrite as LEFT JOIN for clarity)
FULL (OUTER) JOIN — all rows from both tables, NULLs where there is no match
CROSS JOIN — Cartesian product of both tables (every row of A × every row of B)
The ON clause vs USING:
-- ON: explicit column names (flexible)
JOIN departments d ON e.department_id = d.id
-- USING: when column names are identical in both tables
JOIN departments d USING (department_id)
Interview follow-up: What is an anti-join? A LEFT JOIN ... WHERE right_table.key IS NULL — finds rows in the left table with no match in the right table.
Follow-up 1
Can you provide an example of a SQL query using JOIN clause?
Sure! Here's an example of a SQL query using the JOIN clause:
SELECT orders.order_id, customers.customer_name
FROM orders
JOIN customers ON orders.customer_id = customers.customer_id;
In this example, the query retrieves the order_id from the orders table and the customer_name from the customers table. The JOIN clause is used to match the customer_id column in both tables.
Follow-up 2
What are the different types of JOINs in SQL?
There are several types of JOINs in SQL:
- INNER JOIN: Returns only the matching rows between the tables.
- LEFT JOIN: Returns all the rows from the left table and the matching rows from the right table.
- RIGHT JOIN: Returns all the rows from the right table and the matching rows from the left table.
- FULL JOIN: Returns all the rows from both tables, including the non-matching rows.
These JOIN types allow you to control how the rows are combined based on the relationship between the tables.
Follow-up 3
What is the difference between INNER JOIN and OUTER JOIN?
The main difference between INNER JOIN and OUTER JOIN is how they handle non-matching rows:
- INNER JOIN: Returns only the matching rows between the tables. If there is no match, the row is not included in the result set.
- OUTER JOIN: Returns all the rows from one table and the matching rows from the other table. If there is no match, NULL values are used for the columns of the non-matching table.
In other words, INNER JOIN filters out the non-matching rows, while OUTER JOIN includes them in the result set.
Live mock interview
Mock interview: SQL Clauses
- Read your scene and goals
- Talk it out; goals tick off live
- Get a score and stronger lines
Your voice and your AI key never touch our servers; the key stays in this browser and is sent only to Google. Only your round scores are saved to track progress.