Makes sense.  Thanks.

-----Original Message-----
From: sqlite-users-boun...@sqlite.org
[mailto:sqlite-users-boun...@sqlite.org] On Behalf Of Pavel Ivanov
Sent: Wednesday, May 25, 2011 9:37 AM
To: General Discussion of SQLite Database
Subject: Re: [sqlite] Incorrect left join behavior?

> I can use two left joins.  While writing the first left join, I discovered
> that it is behaving like an inner join.
>
> select *
> from test a
>   left join test b on a.component = b.component
> where a.machine = 'machine1'
>   and b.machine = 'machine2';

By the WHERE condition you limit results of your left join only to
those that have b.machine equal to 'machine2' and exclude other 2 rows
where b.machine is null. To get the result you need you have to
rewrite the query in one of the following ways:

select *
from test a left join test b
on a.component = b.component
and b.machine = 'machine2'
where a.machine = 'machine1';

or

select *
from test a left join test b
on a.component = b.component
where a.machine = 'machine1'
and (b.machine is null or b.machine = 'machine2');


I think the first syntax is preferable.


Pavel


On Wed, May 25, 2011 at 9:09 AM, Michael Stephenson
<domehead...@gmail.com> wrote:
> Hi, I have a table as below.  Note that machine1 has 3 components (1-3),
> while machine2 has only 1 components (1).
>
>
>
>
> Machine
>
> Component
>
> Version
>
>
> machine1
>
> component1
>
> 1
>
>
> machine1
>
> component2
>
> 1
>
>
> machine1
>
> component3
>
> 1
>
>
> machine2
>
> component1
>
> 1
>
>
>
> create table test(Machine, Component, Version);
>
> insert into test values('machine1', 'component1', 1);
>
> insert into test values('machine1', 'component2', 1);
>
> insert into test values('machine1', 'component3', 1);
>
> insert into test values('machine2', 'component1', 1);
>
>
>
> I need to see what component versions are different on the machines.  What
I
> really need is a "self outer join", but since SQLite doesn't do outer
joins,
> I can use two left joins.  While writing the first left join, I discovered
> that it is behaving like an inner join.
>
>
>
> select *
>
> from test a
>
>   left join test b on a.component = b.component
>
> where a.machine = 'machine1'
>
>   and b.machine = 'machine2';
>
>
>
>
>
> The expected behavior would be to return 3 rows: one row showing the
> component versions for machine1 and machine2, and two rows showing the
> component version for machine1 with null for machine2.
>
>
>
> The actual behavior is that of an inner join:  I get only one row that
shows
> the component versions for both machines, and the other two components,
> which don't exist for machine2, do not appear in the results at all.
>
>
>
> I'm aware that SQLite only does left joins properly using SQL92 syntax,
> which I am using.  I'm also aware that I'm using a where clause, and the
> docs state that join constraints in a where clause cause a left join to
> behave as an inner join.  However, my where clause does not constrain the
> join expression, just the initial rows involved available to be joined.
>
>
>
> I'm able to work around this by:
>
>
>
> select *
>
> from (select * from test where machine = 'machine1') a
>
>   (select * from test where machine = 'machine2') b
>
> on a.component = b.component;
>
>
>
> But, I just wanted to point this behavior out.  Perhaps I've missed
> something.  It looks like any time there is a where clause, a left join is
> going to behave as an inner join.
>
>
>
> Thanks,
>
>
>
> ~Mike
>
>
>
>
>
> _______________________________________________
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to