Обсуждение: Looking for the correct solution for a generic problem.

Поиск
Список
Период
Сортировка

Looking for the correct solution for a generic problem.

От
Frank Joerdens
Дата:
I've been wondering about this for quite a while now. And I suspect
there is a bog-standard way that is better than the rather clumsy
approach I am following now (it feels clumsy anyway). I've got table B
which is linked to table A as in

CREATE TABLE A (
id        serial,
foo        text,
);

CREATE TABLE B (
a_id        int references A (id),
id        serial,
bar        text
);

Now I want to retrieve rows from A as in

SELECT DISTINCT A.foo
FROM A,B
WHERE A.foo [matches some criteria]
OR B.bar [matches some other criteria]
AND A.id = B.a_id;

This works fine if there is *at least* one row in B for each row in A.
If there isn't, I obviously get 0 results even if the column foo in A
matches the desired criteria. But I do want the rows from A even if
there is no row in B that is linked to those rows in A that match the
criteria. If the column bar in B matches the desired criteria, I also
want the rows in A that are linked to those rows in B.

The solution I am using now is to create a 'dummy' row in B for each row
in A on the application level, which I then filter out of the result
sets again (B gets an extra 'dummy' column which is set to true, if
applicable).

I not only suspect that there is a proper way to do this, but that there
is ample discussion in the relevant literature . . . if I only knew
under which keyword to look it up . . .

Regards, Frank


Re: Looking for the correct solution for a generic problem.

От
Stephan Szabo
Дата:
On Thu, 7 Feb 2002, Frank Joerdens wrote:

> Now I want to retrieve rows from A as in
>
> SELECT DISTINCT A.foo
> FROM A,B
> WHERE A.foo [matches some criteria]
> OR B.bar [matches some other criteria]
> AND A.id = B.a_id;
>
> This works fine if there is *at least* one row in B for each row in A.
> If there isn't, I obviously get 0 results even if the column foo in A
> matches the desired criteria. But I do want the rows from A even if
> there is no row in B that is linked to those rows in A that match the
> criteria. If the column bar in B matches the desired criteria, I also
> want the rows in A that are linked to those rows in B.

Sounds like you want a left outer join.

Maybe...
select distinct a.foo from
a left outer join b on (a.ID = b.a_id)
where a.foo [matches] or B.bar [matches]



Re: Looking for the correct solution for a generic problem.

От
Tom Lane
Дата:
Frank Joerdens <frank@joerdens.de> writes:
> This works fine if there is *at least* one row in B for each row in A.
> If there isn't, I obviously get 0 results even if the column foo in A
> matches the desired criteria. But I do want the rows from A even if
> there is no row in B that is linked to those rows in A that match the
> criteria.

You want an "outer join".  Something likeFROM A LEFT JOIN B ON (A.id = B.a_id)WHERE [other criteria]
        regards, tom lane


Re: Looking for the correct solution for a generic problem.

От
Frank Joerdens
Дата:
On Thu, Feb 07, 2002 at 01:31:03PM -0800, Stephan Szabo wrote:
> On Thu, 7 Feb 2002, Frank Joerdens wrote:
> 
> > Now I want to retrieve rows from A as in
> >
> > SELECT DISTINCT A.foo
> > FROM A,B
> > WHERE A.foo [matches some criteria]
> > OR B.bar [matches some other criteria]
> > AND A.id = B.a_id;
> >
> > This works fine if there is *at least* one row in B for each row in A.
> > If there isn't, I obviously get 0 results even if the column foo in A
> > matches the desired criteria. But I do want the rows from A even if
> > there is no row in B that is linked to those rows in A that match the
> > criteria. If the column bar in B matches the desired criteria, I also
> > want the rows in A that are linked to those rows in B.
> 
> Sounds like you want a left outer join.
> 
> Maybe...
> select distinct a.foo from
> a left outer join b on (a.ID = b.a_id)
> where a.foo [matches] or B.bar [matches]

Ah! There indeed is an entire little chapter (6.6.3) in my 'Fundamentals
of Database Systems' (Elmasri/Navathe) on this, and Bruce talks about it
too . . . albeit saying (in my version of his book) that joins ain't
supported in 7.0 and that you need to simulate 'em using UNION ALL and
subqueries. 

The problem here was a combination of hubris and laziness on my part: I
thought I didn't need to learn about join syntax because I figured it
could all be done with boolean logic as in my query example above . . .

Thanks!

Frank


Re: Looking for the correct solution for a generic problem.

От
Mark Nielsen
Дата:
Frank Joerdens wrote:

> I've been wondering about this for quite a while now. And I suspect
> there is a bog-standard way that is better than the rather clumsy
> approach I am following now (it feels clumsy anyway). I've got table B
> which is linked to table A as in
> 
> CREATE TABLE A (
> id        serial,
> foo        text,
> );
> 
> CREATE TABLE B (
> a_id        int references A (id),
> id        serial,
> bar        text
> );
> 
> Now I want to retrieve rows from A as in
> 
> SELECT DISTINCT A.foo
> FROM A,B
> WHERE A.foo [matches some criteria]
> OR B.bar [matches some other criteria]
> AND A.id = B.a_id;
> 


Perhaps I am clueless, but wouldn't you want to do this

SELECT DISTINCT A.foo FROM A,B WHERE ((A.foo =1) OR (B.bar =2)) AND A.id = B.a_id;

Actually, I think the outerjoin is right.
I had problems like this in the past. I think the other posts answer it.
Mark