Re: Sv: how to build this query ??? Please help !!!

From: Jens Hartwig <jhartwig(at)debis(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Tod McQuillin <devin(at)spamcop(dot)net>, Nikolaj Lundsgaard <Nikolaj(at)konfus(dot)dk>, pgsql-sql(at)postgresql(dot)org
Subject: Re: Sv: how to build this query ??? Please help !!!
Date: 2001-01-04 11:13:54
Message-ID: 3A545AF2.1C827233@debis.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-sql

Hello Tom,

> [...]
> > SELECT a, (SELECT b)
> > FROM xyz;
> [...]
> I think it's OK (we're assuming that a and b are columns of xyz, right?)
> [...]

immediately after having sent my message I realized my fault: a and b
are not of the same table! Correctly, the statement had to be something
like:

SELECT a, (SELECT b FROM z WHERE b = a)
FROM x;

> [...]
> This is not really different from
> SELECT x FROM xyz WHERE y IN
> (SELECT a FROM abc WHERE b = xyz.z);
> [...]

Now it is :-) In a subquery, the inner query is only used for things
like comparison (as it is in your example). In my example the result
shows me two columns (in one record!!) which belong to different tables.
Mmmmh ... I tested the following:

create table x (a numeric);
create table y (b numeric);

insert into x values (1);
insert into x values (2);

insert into y values (1);
insert into y values (2);

select a, (select b from y) from x;

=> ERROR: More than one tuple returned by a subselect used as an
expression.

This is ok, anything else would have shocked me.

select a, (select b from y where b = a) from x;

a | ?column?
----------+----------
1.000000 | 1.000000
2.000000 | 2.000000

This result made me understanding that this special case of "subqueries"
is possibly nothing more than a special form of joins between tables:

select a, b
from x, y
where x.a = y.b;

brings the same result. Now, back to the first example (of Nikolaj):

SELECT a_nr,
(SELECT count(*) FROM cylinders WHERE z_a_nr = a_nr) AS #cylinder,
(SELECT count(*) FROM cylinders WHERE z_a_nr = a_nr AND z_status =
'zdr') AS #zdr,
(SELECT count(*) FROM cylinders WHERE z_a_nr = a_nr AND z_status =
'zcu') AS #zcu,
(SELECT count(*) FROM cylinders WHERE z_a_nr = a_nr AND z_status =
'zcr') AS #zcr,
product, state
FROM orders;

This would be a self-join of one table like:

select ord.a_nr,
c1.count(*),
c2.count(*),
...
from orders ord,
cylinders c1,
cylinders c2,
...
where c1.z_a_nr = ord.a_nr
and c2.z_status = 'zdr'
and ...

This in fact is not possible in PostgreSQL (it seems that the table
alias "c1" cannot be prefixed to the aggregate-function "count(*)") and
AFAIK in no other relational database. I really cannot imagine any
equivalent join-statement (or anything else like a subquery) which
brings the same results! Does this at all correlate with the philosophy
of a relational database?

Best regards, Jens

=============================================
Jens Hartwig
---------------------------------------------
debis Systemhaus GEI mbH
10875 Berlin
Tel. : +49 (0)30 2554-3282
Fax : +49 (0)30 2554-3187
Mobil : +49 (0)170 167-2648
E-Mail : jhartwig(at)debis(dot)com
=============================================

In response to

Responses

Browse pgsql-sql by date

  From Date Subject
Next Message Kovacs Zoltan Sandor 2001-01-04 11:44:14 Re: Support for arrays in PL/pgSQL
Previous Message Tom Lane 2001-01-04 09:46:27 Re: Sv: how to build this query ??? Please help !!!