I am seeing a strange behavior when I do except and union statements in SQL.
I have two tables
Select * from #old
Data looks like this
oid1 oid2 co
1 11 1
2 22 1
3 33 1
4 55 1
Select * from #new
nid1 nid2 co
1 11 3
2 22 1
3 33 1
4 44 1
4 55 1
This is my final query
Select * from #old
except
Select * from #new
union all
Select * from #new
except
Select * from #old
and gives these records
oid1 oid2 co
1 11 3
4 44 1
Question I have is.. Shouldn't there be another row in this from the first except clause:
Select * from #old
except
Select * from #new
which is
oid1 oid2 co
1 11 1
Shouldn't the final query have 3 rows instead of only 2, since not all columns are the same.
You seem to think that the query is interpreted as:
(Select * from #old
except
Select * from #new
)
union all
(Select * from #new
except
Select * from #old
)
But no. It is interpreted as:
((Select * from #old
except
Select * from #new
)
union all
Select * from #new
)
except
Select * from #old
This is equivalent to:
Select * from #new
except
Select * from #old
which is what your query returns.
This is explained in the documentation:
If EXCEPT or INTERSECT is used together with other operators in an expression, it is evaluated in the context of the following precedence:
Expressions in parentheses
The INTERSECT operator
EXCEPT and UNION evaluated from left to right based on their position in the expression