Test whether a subquery returns any rows. Returns TRUE if the subquery produces at least one row, FALSE otherwise. Short-circuits on the first match.
Tests whether a subquery returns any rows, returning TRUE if at least one row exists and FALSE otherwise. More efficient than COUNT(*) > 0 since it stops at the first row. Essential for filtering based on the existence of related rows in another table.
| Database System | Support Status | Since Version | Notes |
|---|---|---|---|
| MySQL | ✓ Supported | all | EXISTS and NOT EXISTS fully supported. The subquery's SELECT list is irrelevant — SELECT 1, SELECT *, SELECT NULL all perform the same. Optimizer may convert to a join internally. |
| PostgreSQL | ✓ Supported | all | EXISTS and NOT EXISTS fully supported. Often faster than IN with large subquery result sets because it short-circuits. The planner typically converts to a semi-join or anti-join. |
| SQL Server | ✓ Supported | all | EXISTS and NOT EXISTS fully supported. Prefer EXISTS over IN when the subquery can return NULLs — NOT IN with NULLs returns no rows (NULL != NULL), while NOT EXISTS handles NULLs correctly. |
| Oracle | ✓ Supported | all | EXISTS and NOT EXISTS fully supported. Oracle's optimizer is good at converting EXISTS to efficient join plans. |
| SQLite | ✓ Supported | all | EXISTS and NOT EXISTS fully supported. |
The NULL trap with NOT IN is the critical gotcha: NOT IN returns zero rows if the subquery result contains any NULL, because SQL can't prove that the value is not equal to NULL. NOT EXISTS handles NULLs correctly and is generally the safer choice. EXISTS short-circuits at the first matching row, making it efficient even for large subqueries.
EXISTS and NOT EXISTS fully supported. The subquery's SELECT list is irrelevant — SELECT 1, SELECT *, SELECT NULL all perform the same. Optimizer may convert to a join internally.
EXISTS and NOT EXISTS fully supported. Often faster than IN with large subquery result sets because it short-circuits. The planner typically converts to a semi-join or anti-join.
EXISTS and NOT EXISTS fully supported. Prefer EXISTS over IN when the subquery can return NULLs — NOT IN with NULLs returns no rows (NULL != NULL), while NOT EXISTS handles NULLs correctly.
EXISTS and NOT EXISTS fully supported. Oracle's optimizer is good at converting EXISTS to efficient join plans.
EXISTS and NOT EXISTS fully supported.