Monday, February 20, 2006

old-school left join, too quirky, sometimes result incorrectly. that's why ansi sql encourage the new left join

create table x
(
a int,
b int
)


create table y
(
a int
)


set nocount on

declare @a int, @b int

set @a = 1
while @a < 20 begin
insert into x(a,b) select @a, @a + 500000
insert into y(a) select @a / 2
set @a = @a + 1
end

insert into y(a) select null

-- query 1: using subquery
select *
from x
where x.a not in(select a from y where a is not null)
order by x.a

-- this join is equivalent to query 1 and is faster
select x.*
from x
left join y on x.a = y.a and y.a is not null
where y.a is null
order by x.a


/*
Note:

-- old way of left joining:
select x.* from x, y where x.a *= y.a

-- new way of left joining(ansi sql compliant):
select x.* from x left join y on x.a = y.a


but when you put other conditions in where clause in old-fashion left join(the *= ), things will get quirky, as you will see in the next queries result

*/

-- incorrect result, the quirks of old-way left join, not equivalent to query 1
select x.*, ya = Y.A
from x, y
where x.a *= y.a and y.a is null


-- incorrect result, still not equivalent to query 1
-- too quirky
select
*
from
(
select x.*, ya = Y.A
from x, y
where x.a *= y.a
) as z
where z.ya is null
order by z.ya

-- this is ok, equivalent to query 1
select
z.a, z.b
from
(
select top 100 percent x.*, ya = Y.A
from x, y
where x.a *= y.a
) as z
where z.ya is null
order by z.a

/* me wondering why have to put TOP 100 PERCENT in the subquery above */




/*
drop table x
drop table y
*/
set nocount off

0 Comments:

Post a Comment

<< Home