A subquery can quite often, but not in all cases, be rewritten as a JOIN.
A subquery using IN
can be rewritten with the DISTINCT
keyword, for example:
SELECT * FROM table1 WHERE col1 IN (SELECT col1 FROM table2);
can be rewritten as:
SELECT DISTINCT table1.* FROM table1, table2 WHERE table1.col1=table2.col1;
NOT IN
or NOT EXISTS
queries can also be rewritten. For example, these two queries returns the same result:
SELECT * FROM table1 WHERE col1 NOT IN (SELECT col1 FROM table2); SELECT * FROM table1 WHERE NOT EXISTS (SELECT col1 FROM table2 WHERE table1.col1=table2.col1);
and both can be rewritten as:
SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id WHERE table2.id IS NULL;
Subqueries that can be rewritten as a LEFT JOIN are sometimes more efficient.
There are some scenarios, though, which call for subqueries rather than joins:
Table_1
has three rows — {1
,1
,2
} — and Table_2
has two rows — {1
,2
,2
}. If you need to list the rows in Table_1
which are also in Table_2
, only this subquery-based SELECT
statement will give the right answer (1
,1
,2
): SELECT Table_1.column_1 FROM Table_1 WHERE Table_1.column_1 IN (SELECT Table_2.column_1 FROM Table_2);
SELECT Table_1.column_1 FROM Table_1,Table_2 WHERE Table_1.column_1 = Table_2.column_1;
1
,1
,2
,2
} — and the duplication of 2 is an error. This SQL statement won't work either: SELECT DISTINCT Table_1.column_1 FROM Table_1,Table_2 WHERE Table_1.column_1 = Table_2.column_1;
1
,2
} — and the removal of the duplicated 1 is an error too. UPDATE Table_1 SET column_1 = (SELECT column_1 FROM Table_2);
SELECT * FROM Table_1 WHERE column_1 + 5 = (SELECT MAX(column_1) FROM Table_2);
SELECT Table_1.* FROM Table_1, (SELECT MAX(column_1) AS max_column_1 FROM Table_2) AS Table_2 WHERE Table_1.column_1 + 5 = Table_2.max_column_1;
SELECT DISTINCT Bookcolumn_1.* FROM Books AS Bookcolumn_1 JOIN Books AS Bookcolumn_2 USING(page_count) WHERE title = 'Das Kapital'; SELECT DISTINCT Bookcolumn_1.* FROM Books AS Bookcolumn_1 WHERE Bookcolumn_1.page_count > (SELECT DISTINCT page_count FROM Books AS Bookcolumn_2 WHERE title = 'Das Kapital');
ANY
book named Das Kapital" (it seems to contain a false assumption that there's only one edition).
© 2019 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/subqueries-and-joins/