Sarah
Sarah

Reputation: 1293

SQL-Union ALL and Except

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.

Upvotes: 5

Views: 5330

Answers (1)

Gordon Linoff
Gordon Linoff

Reputation: 1269623

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:

  1. Expressions in parentheses

  2. The INTERSECT operator

  3. EXCEPT and UNION evaluated from left to right based on their position in the expression

Upvotes: 9

Related Questions