SQL Tutorial
SQL Clauses / Operators
SQL-Injection
SQL Functions
SQL Queries
PL/SQL
MySQL
SQL Server
Misc
The EXCEPT
clause (known as MINUS
in Oracle) is a set operation in SQL that returns the difference between two result sets. It retrieves rows from the first query that are not returned by the second query. Both queries must retrieve the same number of columns, and corresponding columns must have compatible data types.
SELECT column1, column2, ... FROM table1 [WHERE condition] EXCEPT SELECT column1, column2, ... FROM table2 [WHERE condition];
Consider the following tables:
Table Employees
:
ID | Name |
---|---|
1 | Alice |
2 | Bob |
3 | Carol |
Table Managers
:
ID | Name |
---|---|
2 | Bob |
3 | Carol |
If we want to find employees who are not managers:
SELECT ID, Name FROM Employees EXCEPT SELECT ID, Name FROM Managers;
This would return:
ID | Name |
---|---|
1 | Alice |
Alice is the only employee who isn't a manager, so she is the only one returned in the result set.
Order Matters: EXCEPT
retrieves rows from the first query that don't have a match in the second query. Swapping the order of the queries will give different results.
Distinct Results: The EXCEPT
operation inherently removes duplicates. So, if the first query produces duplicates that aren't found in the second query, the result set will only contain one instance of that duplicate.
Compatibility: Not all database systems support EXCEPT
. For example, while SQL Server and PostgreSQL support EXCEPT
, Oracle uses MINUS
for the same operation. Always refer to the documentation for your specific database system.
Matching Columns: Both the queries in the EXCEPT
operation should have the same number of columns, and the data types of these columns should be compatible. If they aren't, you'll get an error.
In scenarios where EXCEPT
or its equivalent isn't available, similar results can often be achieved using LEFT JOIN
with a NULL
check or using a NOT EXISTS
subquery.
SELECT column1 FROM table1 EXCEPT SELECT column1 FROM table2;
SELECT column1 FROM table1 EXCEPT SELECT column1 FROM table2;
SELECT column1 FROM table1 EXCEPT SELECT column1 FROM table2;
SELECT column1 FROM table1 MINUS SELECT column1 FROM table2;
SELECT column1, column2 FROM table1 EXCEPT SELECT column1, column2 FROM table2;
SELECT column1 FROM table1 EXCEPT SELECT column1 FROM table2;
(SELECT column1 FROM table1) EXCEPT (SELECT column1 FROM table2);
SELECT table1.column1 FROM table1 LEFT JOIN table2 ON table1.column1 = table2.column1 WHERE table2.column1 IS NULL;
SELECT column1 FROM table1 WHERE NOT EXISTS (SELECT column1 FROM table2 WHERE table2.column1 = table1.column1);
SELECT column1 FROM table1 EXCEPT SELECT column1 FROM table2;
SELECT column1 FROM table1 EXCEPT SELECT column1 FROM table2;
SELECT column1 FROM table1 WHERE NOT EXISTS (SELECT column1 FROM table2 WHERE table2.column1 = table1.column1);
SELECT column1 FROM table1 EXCEPT SELECT column1 FROM table2;
SELECT table1.column1 FROM table1 LEFT JOIN table2 ON table1.column1 = table2.column1 WHERE table2.column1 IS NULL;
(SELECT column1 FROM table1 EXCEPT SELECT column1 FROM table2) UNION (SELECT column1 FROM table3);
SELECT employee_id FROM employees_in_department1 EXCEPT SELECT employee_id FROM employees_in_department2;
SELECT order_id FROM all_orders EXCEPT SELECT order_id FROM shipped_orders;