Thread: a question on SQL

a question on SQL

From
"Tomi N/A"
Date:
Don't really know where to ask this...the general mailing list sounds
like the closest.

Let's say I have three tables: owner, factory and product with a 1:N
relationship at each step.
Assuming that a product has a production date, how would you go about
returning a factory for every owner, where the returned factory is the
factory that produced the oldest product of it's owner?

I'm perplexed by the simplicity of the task and the fact that what
solutions I did come up with fail to perform very well (a subselect
with ORDER BY MIN(production_date) LIMIT 1) or are rather complex
(using temp tables).

Hints?

TIA,
t.n.a.

Re: a question on SQL

From
Ragnar
Date:
On þri, 2006-12-12 at 16:47 +0000, Tomi N/A wrote:
> Don't really know where to ask this...the general mailing list sounds
> like the closest.
>
> Let's say I have three tables: owner, factory and product with a 1:N
> relationship at each step.
> Assuming that a product has a production date, how would you go about
> returning a factory for every owner, where the returned factory is the
> factory that produced the oldest product of it's owner?


> Hints?

someting like this maybe:
  select distinct on (owner.id,factory.factoryid) *
      from owner,factory,product
      where <your join contitions>
      order by owner.id,factory.factoryid,production_date

gnari




Re: a question on SQL

From
"Marc Mamin"
Date:
Seems that a recursive use of "DISTINCT ON" will do it:




create table factories (id int, factory varchar(10), ownerid int);
create table products (id int, product varchar(10), atime int
,factory_id int);

--owner 1 : factory 1
insert into products values(1,'p1',123,1);
insert into products values(2,'p2',124,1);
insert into products values(3,'p3',125,1);

--owner 1 : factory 2
insert into products values(4,'p4',1,2);-- expected

--owner 2 : factory 3
insert into products values(5,'p5',127,3);-- expected
insert into products values(6,'p6',128,3);
insert into products values(7,'p7',129,3);


insert into factories values(1,'f1',1);
insert into factories values(2,'f2',1);
insert into factories values(3,'f3',2);

select distinct on (foo.ownerid)
foo.ownerid,foo.factory,foo.atime
from
  (select distinct on (f.ownerid, p.factory_id)
  f.ownerid,factory,atime
  from factories f,products p
  where p.factory_id=f.id
  order by f.ownerid, p.factory_id, atime
  )foo
order by foo.ownerid,  foo.atime

Cheers,

Marc

Re: a question on SQL

From
"Tomi N/A"
Date:
Ragnar, Marc, thanks so much for the help: DISTINCT ON was *exactly*
what I needed.
It's not a part of any SQL standard I know of, but does the job _wonderfully_.

Cheers,
t.n.a.

Re: a question on SQL

From
Martijn van Oosterhout
Date:
On Tue, Dec 12, 2006 at 06:29:07PM +0000, Tomi N/A wrote:
> Ragnar, Marc, thanks so much for the help: DISTINCT ON was *exactly*
> what I needed.
> It's not a part of any SQL standard I know of, but does the job
> _wonderfully_.

It's the single most useful non-standard SQL feature postgresql has. It
is thus simultaneously bad (from a portatbility aspect) and brilliant
(because it's a million times easier and faster than the alternatives).

Have a nice day,
--
Martijn van Oosterhout   <kleptog@svana.org>   http://svana.org/kleptog/
> From each according to his ability. To each according to his ability to litigate.

Attachment

Re: a question on SQL

From
"Greg Sabino Mullane"
Date:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


>> Ragnar, Marc, thanks so much for the help: DISTINCT ON was *exactly*
>> what I needed.
>> It's not a part of any SQL standard I know of, but does the job
>> _wonderfully_.

> It's the single most useful non-standard SQL feature postgresql has. It
> is thus simultaneously bad (from a portatbility aspect) and brilliant
> (because it's a million times easier and faster than the alternatives).

You mean second-most useful. LIMIT/OFFSET is the champion, hand down. :)

- --
Greg Sabino Mullane greg@turnstep.com
End Point http://www.endpoint.com/
PGP Key: 0x14964AC8 200612121616
http://biglumber.com/x/web?pk=2529DF6AB8F79407E94445B4BC9B906714964AC8

-----BEGIN PGP SIGNATURE-----

iD8DBQFFfxxjvJuQZxSWSsgRAokYAKDbmzEdfi3B/Fp0L62C6Fn48saMigCfeANo
PFT+tLmygoaZpAqfDO241AQ=
=n0xI
-----END PGP SIGNATURE-----



Re: a question on SQL

From
Tom Lane
Date:
"Greg Sabino Mullane" <greg@turnstep.com> writes:
>> It's the single most useful non-standard SQL feature postgresql has. It
>> is thus simultaneously bad (from a portatbility aspect) and brilliant
>> (because it's a million times easier and faster than the alternatives).

> You mean second-most useful. LIMIT/OFFSET is the champion, hand down. :)

Yeah, but that one's only quasi-non-standard ... several other DBMSes
have it too.

            regards, tom lane

Re: a question on SQL

From
Bruce Momjian
Date:
Tom Lane wrote:
> "Greg Sabino Mullane" <greg@turnstep.com> writes:
> >> It's the single most useful non-standard SQL feature postgresql has. It
> >> is thus simultaneously bad (from a portatbility aspect) and brilliant
> >> (because it's a million times easier and faster than the alternatives).
>
> > You mean second-most useful. LIMIT/OFFSET is the champion, hand down. :)
>
> Yeah, but that one's only quasi-non-standard ... several other DBMSes
> have it too.

I know MySQL has it, and SQL Lite added it.  Which other ones?  Someone
asked me recently.  I see this chart from Perl documentation:

    http://search.cpan.org/~davebaird/SQL-Abstract-Limit-0.12/lib/SQL/Abstract/Limit.pm#DESCRIPTION

Oh, and Rasmus Lerdorf told me he invented LIMIT for mSQL, and MySQL
then added it, and that MySQL added the limit option.

This was interesting in the MySQL manuals:

    For compatibility with PostgreSQL, MySQL also supports the LIMIT
    row_count OFFSET offset syntax.

Did we add the OFFSET _keyword_.  I remember we had the comma-ed numbers
backwards, and we had OFFSET, but I thought that keyword came from
MySQL.  Obviously, they don't think so.

--
  Bruce Momjian   bruce@momjian.us
  EnterpriseDB    http://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

Re: a question on SQL

From
"Gregory S. Williamson"
Date:
Bruce Momjian wrote:
>
> Tom Lane wrote:
> > "Greg Sabino Mullane" <greg@turnstep.com> writes:
> > >> It's the single most useful non-standard SQL feature postgresql has. It
> > >> is thus simultaneously bad (from a portatbility aspect) and brilliant
> > >> (because it's a million times easier and faster than the alternatives).
> >
> > > You mean second-most useful. LIMIT/OFFSET is the champion, hand down. :)
> >
> > Yeah, but that one's only quasi-non-standard ... several other DBMSes
> > have it too.
>
> I know MySQL has it, and SQL Lite added it.  Which other ones?  Someone
> asked me recently.  I see this chart from Perl documentation:
>
>     > http://search.cpan.org/~davebaird/SQL-Abstract-Limit-0.12/lib/SQL/Abstract/Limit.pm#DESCRIPTION
>
> Oh, and Rasmus Lerdorf told me he invented LIMIT for mSQL, and MySQL
> then added it, and that MySQL added the limit option.
>
> This was interesting in the MySQL manuals:
>
>     For compatibility with PostgreSQL, MySQL also supports the LIMIT
>     row_count OFFSET offset syntax.
>
> Did we add the OFFSET _keyword_.  I remember we had the comma-ed numbers
> backwards, and we had OFFSET, but I thought that keyword came from
> MySQL.  Obviously, they don't think so.

Informix provides the "FIRST" syntax to get the leading rows of a set; I think you have to use cursors to get further
offsetsthough (been a while since I have had to use it), e.g. "SELECT FIRST 10 col1, col2, col3 FROM foo WHERE ...". No
"LAST"either (just tried). 

They have had this since at least IDS 8 and I thing the 7.x series had it as well. No idea where they got it from; I
learnedon Informix so I actually thought it was standard, until reality disabused me of the notion. 

Greg Williamson
DBA
GlobeXplorer LLC