Thread:

From
littlesuspense
Date:
Hi Volk,

at first sorry for my English.  I use postgresql very often and I really love it but the syntax for outer join make me sick.
Oracle short notation (+) is also not a best choice at this place but I recall me, that the Informix have a really good and clear syntax:

select * from a, outer b where a.id = b.id;

select * from a, outer( b, outer  c) where a.id = b.id and b.id= c.id;

And surely, I would like to see that also in postgresql.

I hope, I can win you for that.

Sincerely,

LS

Re:

From
Scott Marlowe
Date:
On Mon, Jun 29, 2009 at 2:08 PM, littlesuspense<littlesuspense@web.de> wrote:
> Hi Volk,
>
> at first sorry for my English.  I use postgresql very often and I really
> love it but the syntax for outer join make me sick.
> Oracle short notation (+) is also not a best choice at this place but I
> recall me, that the Informix have a really good and clear syntax:

Note that the word outer is just noise in pgsql, i.e. it's not needed.
 What you've got are left outer, right outer, and full outer joins.
All can be called just left, right, or full joins.  Note that inner
joins are just called joins.

> select * from a, outer b where a.id = b.id;

select * from a full join b on (a.id=b.id) where ...
select * from a left join b on (a.id=b.id) where ...
select * from a join b on (a.id=b.id) where ...

and so on.

> And surely, I would like to see that also in postgresql.

What you get with postgresql is mostly ANSI standard stuff, which
left/right/full outer and inner joins are.

Re:

From
Merlin Moncure
Date:
On Mon, Jun 29, 2009 at 5:11 PM, Scott Marlowe<scott.marlowe@gmail.com> wrote:
> On Mon, Jun 29, 2009 at 2:08 PM, littlesuspense<littlesuspense@web.de> wrote:
>> Hi Volk,
>>
>> at first sorry for my English.  I use postgresql very often and I really
>> love it but the syntax for outer join make me sick.
>> Oracle short notation (+) is also not a best choice at this place but I
>> recall me, that the Informix have a really good and clear syntax:
>
> Note that the word outer is just noise in pgsql, i.e. it's not needed.
>  What you've got are left outer, right outer, and full outer joins.
> All can be called just left, right, or full joins.  Note that inner
> joins are just called joins.
>
>> select * from a, outer b where a.id = b.id;
>
> select * from a full join b on (a.id=b.id) where ...
> select * from a left join b on (a.id=b.id) where ...
> select * from a join b on (a.id=b.id) where ...

also,

select * from a join b using(id) where...;

In simple join cases this is usually the best way to go.

merlin

Re:

From
Waldemar Bergstreiser
Date:
> On Mon, Jun 29, 2009 at 2:08 PM, littlesuspense<littlesuspense@web.de> wrote:
> > Hi Volk,
> >
> Note that the word outer is just noise in pgsql, i.e. it's not needed.
>  What you've got are left outer, right outer, and full outer joins.
> All can be called just left, right, or full joins.  Note that inner
> joins are just called joins.
>
> > select * from a, outer b where a.id = b.id;
>
> select * from a full join b on (a.id=b.id) where ...
> select * from a left join b on (a.id=b.id) where ...
> select * from a join b on (a.id=b.id) where ...

this is only a simple case, but outer can make syntax more clean in complicated joins.
Just try to rewrite query below with left outter joins. I had not found any compact syntax.

-- c *= b *= a =* d =* f
select * from a, outer( b, outer c), outer (d, outer f )
where a.b_id = b.id and b.c_id = c.id and a.d_id = d.id and d.f_id = f.id;

>
> and so on.
>
> > And surely, I would like to see that also in postgresql.
>
> What you get with postgresql is mostly ANSI standard stuff, which
> left/right/full outer and inner joins are.
>
And I like that, but each SQL RDMS system and each SQL dialect de facto provide also a lot of standard extensions. So
theRDMS user has a choice, to use such extensions or not. And I think postgres can only win if we it have more and very
saneextensions. 

I think so.

______________________________________________________
GRATIS für alle WEB.DE-Nutzer: Die maxdome Movie-FLAT!
Jetzt freischalten unter http://movieflat.web.de


Re:

From
Scott Marlowe
Date:
On Tue, Jun 30, 2009 at 2:00 AM, Waldemar
Bergstreiser<littlesuspense@web.de> wrote:
>> On Mon, Jun 29, 2009 at 2:08 PM, littlesuspense<littlesuspense@web.de> wrote:
>> > Hi Volk,
>> >
>> Note that the word outer is just noise in pgsql, i.e. it's not needed.
>>  What you've got are left outer, right outer, and full outer joins.
>> All can be called just left, right, or full joins.  Note that inner
>> joins are just called joins.
>>
>> > select * from a, outer b where a.id = b.id;
>>
>> select * from a full join b on (a.id=b.id) where ...
>> select * from a left join b on (a.id=b.id) where ...
>> select * from a join b on (a.id=b.id) where ...
>
> this is only a simple case, but outer can make syntax more clean in complicated joins.
> Just try to rewrite query below with left outter joins. I had not found any compact syntax.
>
> -- c *= b *= a =* d =* f
> select * from a, outer( b, outer c), outer (d, outer f )
> where a.b_id = b.id and b.c_id = c.id and a.d_id = d.id and d.f_id = f.id;

from a full join b on (a.id=b.id)
full join c on (b.id=c.id)
full join d

and so on.  Doesn't seem any lestt compact or readable to me.
>> What you get with postgresql is mostly ANSI standard stuff, which
>> left/right/full outer and inner joins are.
>>
> And I like that, but each SQL RDMS system and each SQL dialect de facto provide also a lot of standard extensions. So
theRDMS user has a choice, to use such extensions or not. And I think postgres can only win if we it have more and very
saneextensions. 

If the standard SQL syntax does the job, I see no reason to include
non-standard syntax from other dbs unless they're obviously cleaner
and simpler, and I really don't see that here.  Every thing you add to
the query planner / executor costs something in planning and / or
execution times.

Further, most database engines now support sql standard join syntax,
so there's no great reason to support it for compatibility reasons.

Re:

From
Waldemar Bergstreiser
Date:
> -----Ursprüngliche Nachricht-----
> Von: "Scott Marlowe" <scott.marlowe@gmail.com>
> Gesendet: 30.06.09 10:17:11
> An: Waldemar Bergstreiser <littlesuspense@web.de>
> CC: pgsql-general@postgresql.org
> Betreff: Re: [GENERAL]


> On Tue, Jun 30, 2009 at 2:00 AM, Waldemar
> Bergstreiser<littlesuspense@web.de> wrote:
> >> On Mon, Jun 29, 2009 at 2:08 PM, littlesuspense<littlesuspense@web.de> wrote:
> >> > Hi Volk,
> >> >
> >> Note that the word outer is just noise in pgsql, i.e. it's not needed.
> >>  What you've got are left outer, right outer, and full outer joins.
> >> All can be called just left, right, or full joins.  Note that inner
> >> joins are just called joins.
> >>
> >> > select * from a, outer b where a.id = b.id;
> >>
> >> select * from a full join b on (a.id=b.id) where ...
> >> select * from a left join b on (a.id=b.id) where ...
> >> select * from a join b on (a.id=b.id) where ...
> >
> > this is only a simple case, but outer can make syntax more clean in complicated joins.
> > Just try to rewrite query below with left outter joins. I had not found any compact syntax.
> >
> > -- c *= b *= a =* d =* f
> > select * from a, outer( b, outer c), outer (d, outer f )
> > where a.b_id = b.id and b.c_id = c.id and a.d_id = d.id and d.f_id = f.id;
>
> from a full join b on (a.id=b.id)
> full join c on (b.id=c.id)
> full join d
>

I guess, you don't get it. Probably so

select * from a left outer join b on (a.b_id=b.id) ....

But I don't see any clear way to specify that table C should be outer joined only if we got a row from table B.


> and so on.  Doesn't seem any lestt compact or readable to me.
> >> What you get with postgresql is mostly ANSI standard stuff, which
> >> left/right/full outer and inner joins are.
> >>
> > And I like that, but each SQL RDMS system and each SQL dialect de facto provide also a lot of standard extensions.
Sothe RDMS user has a choice, to use such extensions or not. And I think postgres can only win if we it have more and
verysane extensions. 
>
> If the standard SQL syntax does the job, I see no reason to include
> non-standard syntax from other dbs unless they're obviously cleaner
> and simpler, and I really don't see that here.  Every thing you add to
> the query planner / executor costs something in planning and / or
> execution times.

I am fully agreed with you. My point is, that the syntax with outer is much clearer
and can't be so easy rewritten in standard ANSI SQL.
And I hope this can be implemented in SQL parser so the planner is not affected, and on the other side,
the reduction of overall SQL statement's length can have a positive impact on network traffic and speed of SQL parsing.


>
> Further, most database engines now support sql standard join syntax,
> so there's no great reason to support it for compatibility reasons.
>

This suggestion is not caused by compatibility consideration. It's just a try to take over a good things from oldies
RDMS.


______________________________________________________
GRATIS für alle WEB.DE-Nutzer: Die maxdome Movie-FLAT!
Jetzt freischalten unter http://movieflat.web.de


Re:

From
Greg Stark
Date:
On Tue, Jun 30, 2009 at 9:58 AM, Waldemar
Bergstreiser<littlesuspense@web.de> wrote:
>> > -- c *= b *= a =* d =* f
>> > select * from a, outer( b, outer c), outer (d, outer f )
>> > where a.b_id = b.id and b.c_id = c.id and a.d_id = d.id and d.f_id = f.id;
>>
>> from a full join b on (a.id=b.id)
>> full join c on (b.id=c.id)
>> full join d
>>
>
> I guess, you don't get it. Probably so

I don't get it either.  by *= do you mean the Oracle-style outer join?
in which case why is this not just

select * from a,
left outer join b on (a.b_id = b.id)
left outer join c on (b.c_id = c.id)
left outer join d on (a.d_id = d.id)
left outer join f  on (d.f_id = f.id)

You can parenthesize it different ways but I think the result in this
case is actually the same.

> select * from a left outer join b on (a.b_id=b.id) ....
>
> But I don't see any clear way to specify that table C should be outer joined only if we got a row from table B.

Well that would be the default since if you get no row from b b.c_id
will be null.



--
greg
http://mit.edu/~gsstark/resume.pdf

Re:

From
Waldemar Bergstreiser
Date:
> >> > -- c *= b *= a =* d =* f
> >> > select * from a, outer( b, outer c), outer (d, outer f )
> >> > where a.b_id = b.id and b.c_id = c.id and a.d_id = d.id and d.f_id = f.id;
> >>
> >> from a full join b on (a.id=b.id)
> >> full join c on (b.id=c.id)
> >> full join d
> >>
> >
> > I guess, you don't get it. Probably so
>
> I don't get it either.  by *= do you mean the Oracle-style outer join?
> in which case why is this not just
>
> select * from a,
> left outer join b on (a.b_id = b.id)
> left outer join c on (b.c_id = c.id)
> left outer join d on (a.d_id = d.id)
> left outer join f  on (d.f_id = f.id)
>

The equal expression would be like this:

select * from a
left outer join (b left outer join c on (b.c_id = c.id) ) on (a.b_id = b.id)
left outer join (d left outer join f  on (d.f_id = f.id) ) on (a.d_id = d.id)

and that is a double length of original SQL and has not very clear syntax in my opinion.
Additionally it can be very funny if we try to append a join conditions like "c.iso = d.iso"

> You can parenthesize it different ways but I think the result in this
> case is actually the same.
>

I'm not sure.

> > select * from a left outer join b on (a.b_id=b.id) ....
> >
> > But I don't see any clear way to specify that table C should be outer joined only if we got a row from table B.
>
> Well that would be the default since if you get no row from b b.c_id
> will be null.
>

and if I have a row in table C where c.id is null? A don't know.

I found a good explanation about informix outer joins.

http://savage.net.au/SQL/outer-joins.html

Please take a look at that.


________________________________________________________________
Neu: WEB.DE Doppel-FLAT mit Internet-Flatrate + Telefon-Flatrate
für nur 19,99 Euro/mtl.!* http://produkte.web.de/go/02/


Re:

From
Tom Lane
Date:
Waldemar Bergstreiser <littlesuspense@web.de> writes:
> Just try to rewrite query below with left outter joins. I had not found any compact syntax.

> select * from a, outer( b, outer c), outer (d, outer f )
> where a.b_id = b.id and b.c_id = c.id and a.d_id = d.id and d.f_id = f.id;

This has got pretty much the same problem as Oracle's syntax: there's no
principled way to decide what it *means*.  Which join is each of the
WHERE conditions supposed to be attached to, and why?  What do you do if
you want a behavior slightly different from whatever the engine decides
it means?

The standard's syntax is a bit more verbose, but at least it's perfectly
clear which conditions are outer-join conditions and which are filters.

            regards, tom lane

Re:

From
Erik Jones
Date:
On Jun 30, 2009, at 4:14 AM, Waldemar Bergstreiser wrote:

>> I don't get it either.  by *= do you mean the Oracle-style outer
>> join?
>> in which case why is this not just
>>
>> select * from a,
>> left outer join b on (a.b_id = b.id)
>> left outer join c on (b.c_id = c.id)
>> left outer join d on (a.d_id = d.id)
>> left outer join f  on (d.f_id = f.id)
>>

<snip>

>
>>> select * from a left outer join b on (a.b_id=b.id) ....
>>>
>>> But I don't see any clear way to specify that table C should be
>>> outer joined only if we got a row from table B.
>>
>> Well that would be the default since if you get no row from b b.c_id
>> will be null.
>>
>
> and if I have a row in table C where c.id is null? A don't know.

No, it's perfectly clear as 'NULL = NULL' evaluates to false:

postgres=# select null = null;
  ?column?
----------

(1 row)

Erik Jones, Database Administrator
Engine Yard
Support, Scalability, Reliability
866.518.9273 x 260
Location: US/Pacific
IRC: mage2k






Re:

From
David Fetter
Date:
On Tue, Jun 30, 2009 at 10:22:23AM -0700, Erik Jones wrote:
>
> postgres=# select null = null;
>  ?column?
> ----------
>
> (1 row)

Actually, it's NULL.

shackle@postgres:5432=# SELECT (NULL = NULL) IS NULL;
 ?column?
----------
 t
(1 row)

Cheers,
David.
--
David Fetter <david@fetter.org> http://fetter.org/
Phone: +1 415 235 3778  AIM: dfetter666  Yahoo!: dfetter
Skype: davidfetter      XMPP: david.fetter@gmail.com

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate

Re:

From
Merlin Moncure
Date:
On Tue, Jun 30, 2009 at 1:22 PM, Erik Jones<ejones@engineyard.com> wrote:
>> and if I have a row in table C where c.id is null? A don't know.
>
> No, it's perfectly clear as 'NULL = NULL' evaluates to false:
>
> postgres=# select null = null;
>  ?column?
> ----------
>

you can test for that with 'is distinct from':

select null is distinct from null;  -- false
select null is distinct from 1;  -- true

Re:

From
Erik Jones
Date:
On Jun 30, 2009, at 11:25 AM, David Fetter wrote:

> On Tue, Jun 30, 2009 at 10:22:23AM -0700, Erik Jones wrote:
>>
>> postgres=# select null = null;
>> ?column?
>> ----------
>>
>> (1 row)
>
> Actually, it's NULL.
>
> shackle@postgres:5432=# SELECT (NULL = NULL) IS NULL;
> ?column?
> ----------
> t
> (1 row)

Er, yeah, I mispoke, my point was that it doesn't evaluate to TRUE so
the join doesn't hit a match, though...

Erik Jones, Database Administrator
Engine Yard
Support, Scalability, Reliability
866.518.9273 x 260
Location: US/Pacific
IRC: mage2k






Re:

From
Sam Mason
Date:
On Tue, Jun 30, 2009 at 01:14:10PM +0200, Waldemar Bergstreiser wrote:
> I found a good explanation about informix outer joins.
>
> http://savage.net.au/SQL/outer-joins.html
>
> Please take a look at that.

The syntax appears to make the expression of various idioms difficult;
for example, how would I express the following:

  SELECT *
  FROM a LEFT JOIN b ON a.id = b.id
  WHERE b.id IS NULL OR a.c <> b.d;

Admittedly I don't write code like this very often but, yes, I have used
it on some occasions.  I guess I'd have to resort to a subselect?


I believe this is what Tom was referring to when he said that "there's
no principled way to decide what it *means*".  For example the semantics
of the above are very different from either of:

  SELECT *
  FROM a LEFT JOIN b ON a.id = b.id OR a.c <> b.d
  WHERE b.id IS NULL;

or:

  SELECT *
  FROM a LEFT JOIN b ON a.id = b.id AND (b.id IS NULL OR a.c <> b.d)

and I can't think of any other formulations after reading the link you
gave---it only seems to talk about binary operators involving columns
from two tables.  Second shouldn't be allowed, but I included it in case
I was missing something.

--
  Sam  http://samason.me.uk/