Search code examples
mysqlrelational-division

SQL catch 22 in nested queries ? (what is the order of execution ?)


Suppose we have a table vv and a table r
We run the following query to simulate a set division.

I understand this query runs like a nested for-loop
The question is this: In the deepest nested query how can we use table vv1 while it's construction is not yet complete ?

I thought the 'select' clause is the last one to be computed, so how does mysql know that vv1 has distinct values (or which values it has at all) before completing the where clause, but to complete the where clause it must completed it first ?

SELECT DISTINCT vv1.y
FROM   vv AS vv1
WHERE  NOT EXISTS (SELECT r.A
                   FROM   r
                   WHERE  r.A NOT IN (SELECT vv2.x
                                      FROM   vv AS vv2
                                      WHERE  vv2.y = vv1.y)); 


+------+ Table r
| A    |
+------+
|    1 |
|    2 |
|    3 |
+------+

+------+------+ Table vv
| x    | y    |
+------+------+
|    1 | A    |
|    2 | A    |
|    3 | A    |
|    1 | B    |
|    2 | B    |
|    3 | C    |
|    3 | D    |
+------+------+

Try it here: SQLFIDDLE


Solution

  • This is a correlated subquery. For each row in the main vv1 table, it runs the subquery with all the vv.colName values replaced with the corresponding entries from the main table. So it doesn't try to compute the inner query all at once, it does it repeatedly for each row of vv1.

    See also this tutorial on correlated subqueries, it includes an example where the subquery is in the WHERE clause.