Re: using top-level aggregate values in subqueries

From: "Ossie J(dot) H(dot) Moore" <ossie(dot)moore(at)home(dot)com>
To: pgsql-sql(at)postgresql(dot)org
Subject: Re: using top-level aggregate values in subqueries
Date: 2001-04-24 04:31:06
Message-ID: 01042323310601.28922@okmoore.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-sql

Subject: Re: [SQL] using top-level aggregate values in subqueries
Date: Mon, 23 Apr 2001 23:24:48 -0500
From: Ossie J. H. Moore <ossie(dot)moore(at)home(dot)com>
To: "Thomas F. O'Connell" <tfo(at)monsterlabs(dot)com>

I'm a little unclear on what you are trying to do here so I'll take a stab at
explaining how you can compare two or more columns to the same columns in a
sub query...

1. Let's assume you have three tables:

CUSTomers (cust_id, cust_name),
MAGazines (mag_id, mag_name),
TERMs (cust_id, mag_id, mag_expire) where expire is an int2 representing the
year.

Values in the tables are as follows:

CUST: 1, JACK; 2, JILL; 3, JOE
MAG: 1, DOGS; 2, CATS
TERM: 1,1,2000; 1,1,2001; -- JACK subscribed to DOGS in 2000,2001
2,1,2000; -- JILL subscribed to DOGS in 2000
2,2,2001; -- JILL subscribed to CATS in 2001
3,2,2000; 3,2,2001; -- JOE subscribed to CATS IN 2000,2001

2. You want to see a list of customer and magazine name pairs of those
expiring in 2001.

SELECT C.CUST_NAME, M.MAG_NAME
FROM CUST C, MAG M
WHERE (C.CUST_ID, M.MAG_ID) IN
(
SELECT T.CUST_ID, T.MAG_ID
FROM TERM T
WHERE T.TERM_EXPIRE = 2001
)
ORDER BY C.CUST_NAME, M.MAG_NAME

3. For this specific situation, the better solution might have been the
statement below but the intent was to show how to match multiple columns in
your parent query to multiple columns in a sub query.

select c.cust_name
, m.mag_name
from cust c
, mag m
, term t
where c.cust_id = t.cust_id
and m.mag_id = t.mag_id
and t.term_expire = 2001;

On Monday 23 April 2001 19:26, you wrote:
> from the docs, i know that if you have two tables, foo and bar, you can
> write a query such as
>
> select f.bling
> from foo f
> where f.id = (
> select max( b.id )
> from bar b
> where b.bling = "i kiss you!"
> );
>
> what i'm wondering is if you need that subquery in two places in a query
> if there's some way to cache it at the top level.
>
> for instance, if i were shooting for
>
> select f.id
> from foo f, ola o
> where f.id = (
> select max( b.id )
> from bar b
> where b.bling = "i kiss you!"
> )
> and o.id != (
> select max( b.id )
> from bar b
> where b.bling = "i kiss you!"
> )
>
> is there some way to grab the value returned by the subquery in the
> superquery and use the value instead of running the subquery twice?
>
> i'm not looking for an optimized version of my example (unless it
> answers the question of the bigger picture); i'd rather know if there's
> some way to access top-level aggregates from within a subquery.
>
> or find out that postgres is smart enough to recognize bits of SQL in a
> query that are identical and do its own internal caching.
>
> generically stated, my question is:
>
> is there some way, without writing a function, to calculate an aggregate
> value in a query that is used in multiple subqueries without needing to
> run an aggregating query multiple times?
>
> i know it only amounts to syntactic sugar, but, as such, it would be
> pretty sweet.
>
> thanks.
>
> -tfo
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: Have you checked our extensive FAQ?
>
> http://www.postgresql.org/users-lounge/docs/faq.html

-------------------------------------------------------

Browse pgsql-sql by date

  From Date Subject
Next Message Cedar Cox 2001-04-24 10:16:11 Re: Timezone conversion
Previous Message Tom Lane 2001-04-24 02:20:29 Re: using top-level aggregate values in subqueries