SQL Subqueries and Correlated Subqueries: How to Read, Write and Solve Placement-Test Questions

Read nested SQL from the inside out, distinguish once-only and per-row evaluation, and solve common placement questions with one small employee dataset.

KnowledgeGate Team

Exam prep & CS education

Updated 29 Jul 20265 min read

Many students can write a plain SELECT but lose track when one query appears inside another. The real difficulty is usually one question: does the inner query stand alone, or does it need a value from the current outer row?

Once you can spot that dependency, subquery questions become a sequence of small evaluations instead of one intimidating statement.

The one idea that unlocks every subquery

A subquery is a SELECT nested inside another SQL statement. It can supply one scalar value, a column of values, or a table-shaped result.

The main fork is dependency:

  • A non-correlated subquery does not refer to the outer query. In the usual placement-test model, evaluate it once and reuse its result.

  • A correlated subquery refers to a column from the current outer row. Conceptually, evaluate it again for each candidate outer row.

Database optimisers may transform either form internally, but the conceptual model above is what lets you predict the result correctly.

Position also tells you the result's job. A subquery in WHERE supplies a filter. One in FROM becomes a derived table. One in SELECT normally supplies a scalar value for each output row.

The employee and department tables

Every worked answer below uses these five employees:

emp_id

name

dept_id

salary

1

Asha

10

50000

2

Ravi

10

70000

3

Neha

20

60000

4

Vikram

20

45000

5

Priya

30

80000

The department lookup is:

dept_id

dept_name

10

Sales

20

Engineering

30

Research

Keep the data visible as you read. Placement questions often use tiny tables precisely so that you can compute each result by hand.

Non-correlated subquery: runs once

Suppose the question asks for employees earning more than the company average:

SELECT name
FROM Employee
WHERE salary > (SELECT AVG(salary) FROM Employee);

Nothing in the inner query refers to the outer row. Compute its scalar result:

AVG = (50000 + 70000 + 60000 + 45000 + 80000) / 5

The numerator is 305000, so AVG = 305000 / 5 = 61000.

The outer query is now equivalent to filtering on salary > 61000. Ravi earns 70000 and Priya earns 80000, so they pass. Asha at 50000, Neha at 60000, and Vikram at 45000 fail. The answer is Ravi and Priya.

Read the parentheses first. If they can run without any outer alias, write down their result, then solve the outer query with that value.

Correlated subquery: runs per row

Now change the question: find employees earning more than the average salary of their own department.

SELECT e.name
FROM Employee e
WHERE e.salary > (
    SELECT AVG(x.salary)
    FROM Employee x
    WHERE x.dept_id = e.dept_id
);

The reference to e.dept_id creates the correlation. Walk through all five outer employees:

  • Department 10 average is (50000 + 70000) / 2 = 120000 / 2 = 60000. Asha's 50000 fails and Ravi's 70000 passes.

  • Department 20 average is (60000 + 45000) / 2 = 105000 / 2 = 52500. Neha's 60000 passes and Vikram's 45000 fails.

  • Department 30 average is 80000 / 1 = 80000. Priya earns exactly 80000, so she does not satisfy the strict > comparison.

The answer is Ravi and Neha. If the operator were >=, Priya would also pass. That one-character boundary is a favourite predict-the-output twist.

EXISTS and NOT EXISTS

EXISTS asks whether the inner query can produce at least one row. The selected expression is irrelevant, which is why SELECT 1 is conventional.

SELECT d.dept_name
FROM Department d
WHERE EXISTS (
    SELECT 1
    FROM Employee e
    WHERE e.dept_id = d.dept_id
      AND e.salary > 65000
);

For Sales, Ravi at 70000 supplies a match. Engineering has no salary above 65000, because its maximum is Neha's 60000. Research has Priya at 80000. The answer is Sales and Research.

Think of EXISTS as a true-or-false presence test that can stop as soon as one matching row turns up, which is why it often beats counting rows you do not need.

NOT EXISTS is the same machinery with its answer inverted. To list the departments where nobody earns above 65000:

SELECT d.dept_name
FROM Department d
WHERE NOT EXISTS (
    SELECT 1
    FROM Employee e
    WHERE e.dept_id = d.dept_id
      AND e.salary > 65000
);

Sales is excluded because of Ravi and Research because of Priya. Engineering has nobody above 65000, so the answer is Engineering alone. Unlike NOT IN, this stays reliable when the compared column holds a NULL, because EXISTS only asks whether a row came back, and that question is always true or false.

The worked examples in SQL Queries and Joins in DBMS help you recognise when the same question can be expressed as a join.

Traps that cost the mark

A scalar operator with several rows

= (SELECT ...) expects one value. If the subquery returns several rows, the database raises an error. Use IN for membership, or use ANY or ALL when the question calls for a quantified comparison.

NOT IN with NULL

If the subquery behind NOT IN contains even one NULL, comparisons against that unknown value prevent the predicate from becoming true in the expected way. The outer query can return no rows. Prefer a properly correlated NOT EXISTS when nulls are possible.

Correlation hidden in an alias

Do not decide by indentation. Scan the inner query for an outer alias. A reference such as e.dept_id is the dependency that makes the query correlated.

Correct result, avoidable repeated work

A correlated form may express the requirement clearly, but it can be expensive on large data. A database may decorrelate it, or you can rewrite it with a join to a grouped derived table. Compare both forms and inspect the plan when performance matters.

For exam-style edge cases, DBMS SQL Query MCQs gives focused practice on SELECT, joins, and subqueries.

How placement tests and interviews frame this

Online assessments commonly give a small table and ask you to predict the result. Interviews may ask you to rewrite a correlated subquery as a join, explain EXISTS versus IN, or diagnose a NOT IN query that unexpectedly returns nothing.

Say your reasoning aloud: identify the inner result shape, check for an outer reference, compute the inner result, then apply the outer predicate. KnowledgeGate's question bank has over 2,000 DBMS questions, including SELECT, joins, and subqueries. The CS Fundamentals for Placements category connects this SQL practice with the wider placement syllabus.

The short version and your next step

Read the inner query first. If it does not need an outer value, compute it once in your hand trace. If it names an outer column, evaluate it for each candidate row. Use EXISTS and NOT EXISTS for presence checks, and treat NOT IN cautiously when nulls are possible.

Next, practise each shape in Coding for Placements: one scalar subquery, one correlated average, one EXISTS, and one null-safe NOT EXISTS. For every query, write the intermediate result before you run it.