Subqueries
Subqueries
Section titled βSubqueriesβWhat it means
Section titled βWhat it meansβA subquery is a query nested inside another query, used wherever a single value, a list of values, or a table-like result is needed. Common forms: a scalar subquery in WHERE or SELECT (returns one value), IN/NOT IN with a list of values, and EXISTS/NOT EXISTS for existence checks.
Examples
Section titled βExamplesβ-- Scalar subquery: compare against a single computed valueSELECT Name, Salary FROM EmployeesWHERE Salary > (SELECT AVG(Salary) FROM Employees);
-- IN: match against a list produced by another querySELECT Name FROM CustomersWHERE Id IN (SELECT CustomerId FROM Orders WHERE Amount > 1000);
-- EXISTS: often faster than IN for large sets, checks existence onlySELECT Name FROM Customers cWHERE EXISTS (SELECT 1 FROM Orders o WHERE o.CustomerId = c.Id);
-- Subquery in the SELECT listSELECT Name, (SELECT COUNT(*) FROM Orders o WHERE o.CustomerId = c.Id) AS OrderCountFROM Customers c;
-- Subquery as a derived table (in the FROM clause)SELECT dept, avg_salary FROM ( SELECT DepartmentId AS dept, AVG(Salary) AS avg_salary FROM Employees GROUP BY DepartmentId) AS DeptAveragesWHERE avg_salary > 60000;Common mistake
Section titled βCommon mistakeβUsing NOT IN with a subquery that can return NULL values β if even one value in the subqueryβs result is NULL, the entire NOT IN comparison silently returns zero rows, which is a notorious SQL gotcha.
-- If ANY CustomerId in Orders is NULL, this returns NO rows at all, even for-- customers who genuinely have no orders -- silently wrong, no error raisedSELECT Name FROM CustomersWHERE Id NOT IN (SELECT CustomerId FROM Orders);
-- Fix: filter out NULLs explicitly, or use NOT EXISTS insteadSELECT Name FROM Customers cWHERE NOT EXISTS (SELECT 1 FROM Orders o WHERE o.CustomerId = c.Id);Quick practice
Section titled βQuick practiceβ-
Whatβs the danger of using
NOT INwith a subquery that might return NULL values?Answer
If any row in the subquery's result is NULL, the entireNOT INcondition silently evaluates to no matches at all β no error, just an unexpectedly empty result set. -
Whatβs the difference between
INandEXISTS?Answer
INcompares a value against a list of values from the subquery;EXISTSjust checks whether the subquery returns any rows at all, and is often more efficient (and safer regarding NULLs) for large result sets. -
Can a subquery be used in the
FROMclause of an outer query?Answer
Yes β this is called a derived table, and it must be given an alias, e.g.FROM (SELECT ...) AS AliasName.