Thread: HAVING in EXISTS-clause ...

HAVING in EXISTS-clause ...

From
marten@feki.toppoint.de
Date:
Hello PostgreSQL user,

we're haveing some trouble when doing the following commands:

a) This statement works very well ...

SELECT AO,AT,AV FROM P3AT
GROUB BY AO
HAVING COUNT(*)>1


b) This statement works very well ...

SELECT AO,AT,AV FROM P3AT AS OAT 
WHERE EXISTS(  SELECT AO FROM P3AT  WHERE    AO = OAT.AO  GROUB BY AO)

c) This statement does NOT work. It gives an error message:  "rewrite: aggregate column of view must be ar rigth side
inqual"
 

SELECT AO,AT,AV FROM P3AT AS OAT
WHEREEXISTS(  SELECT AO FROM P3AT  WHERE    AO = OAT.AO  GROUP BY AO  HAVING COUNT(*) = 8)

The meaning of the statement is: return the result as triples, but
make sure, that you return only these results, where you have 
eight result rows available for each AO.

Perhaps someone may help me !?

Marten






Re: [SQL] HAVING in EXISTS-clause ...

From
Stuart Rison
Date:
It's just a case of reversing the order of the aggregate and the constant
in your qualifier (as hinted to by the error message).

This worked for me

SELECT [DISTINCT] AO,AT,AV FROM P3AT AS OAT
WHEREEXISTS(  SELECT AO FROM P3AT  WHERE    AO = OAT.AO  GROUP BY AO  HAVING 8 = COUNT(*)  );

I put the DISTINCT in square brackets to indicate that it is optional.
The statement will select all rows from sets with 8 indentical
AOs.  Without the DISTINCT, all such instances will be returned, with the
DISTINCT, only row with different combinations of AO, AT and AV are
returned.  Note that with the DISTINCT you have no way of indentifying
which exact row has been returned from set with identical AO,AT and AV
combinations.

As an aside, is it worth changing the error message to something like:

"ERROR:  rewrite: aggregate column of view must be at rigth side in qual.
Try exchanging the position of the aggregate with the value it is compared
to."

or should we in fact avoid such error messages? 

Regards,

S. 

On Tue, 9 Nov 1999 marten@feki.toppoint.de wrote:

> Hello PostgreSQL user,
> 
> we're haveing some trouble when doing the following commands:
> 
> a) This statement works very well ...
> 
> SELECT AO,AT,AV FROM P3AT
> GROUB BY AO
> HAVING COUNT(*)>1
> 
> 
> b) This statement works very well ...
> 
> SELECT AO,AT,AV FROM P3AT AS OAT 
> WHERE 
>  EXISTS(
>    SELECT AO FROM P3AT
>    WHERE
>      AO = OAT.AO
>    GROUB BY AO)
> 
> c) This statement does NOT work. It gives an error message:
>    "rewrite: aggregate column of view must be ar rigth side in qual"
> 
> SELECT AO,AT,AV FROM P3AT AS OAT
> WHERE
>  EXISTS(
>    SELECT AO FROM P3AT
>    WHERE
>      AO = OAT.AO
>    GROUP BY AO
>    HAVING COUNT(*) = 8)
> 
> The meaning of the statement is: return the result as triples, but
> make sure, that you return only these results, where you have 
> eight result rows available for each AO.
> 
> Perhaps someone may help me !?
> 
> Marten
> 
> 
> 
>  
> 
> 
> ************
> 

Stuart C. G. Rison
Department of Biochemistry and Molecular Biology
6th floor, Darwin Building, University College London (UCL)
Gower Street, London, WC1E 6BT, United Kingdom
Tel. 0207 504 2303, Fax. 0207 380 7193
e-mail: rison@biochem.ucl.ac.uk



Re: [SQL] HAVING in EXISTS-clause ...

From
Tom Lane
Date:
Stuart Rison <rison@biochemistry.ucl.ac.uk> writes:
> It's just a case of reversing the order of the aggregate and the constant
> in your qualifier (as hinted to by the error message).

> This worked for me

> SELECT [DISTINCT] AO,AT,AV FROM P3AT AS OAT
> WHERE
>  EXISTS(
>    SELECT AO FROM P3AT
>    WHERE
>      AO = OAT.AO
>    GROUP BY AO
>    HAVING 8 = COUNT(*)
>    );

Marten has actually stumbled across a bug here: the rewriter mistakenly
thinks that COUNT() appears in the outer SELECT's WHERE clause (well,
it does, but since it's inside a sub-select it really belongs to the
inner SELECT) and is trying to rewrite the query to push the COUNT()
into yet a third level of SELECT.  That doesn't hurt in this case, but
in other cases it generates the wrong answer.

The "must be at right side in qual" message appears because the rewriter
only knows how to push down COUNT() on the right side of an operator.
That's a pretty bogus limitation, but the whole thing is really pretty
bogus --- none of that rewriter code would exist if we could handle views
involving aggregate functions as sub-selects in FROM.  So it's probably
not worth any effort to add more code to a routine that shouldn't exist
in the first place; we've got to work on the fundamental problem
instead.
        regards, tom lane


Re: [SQL] HAVING in EXISTS-clause ...

From
marten@feki.toppoint.de
Date:
Hello all out there,

> involving aggregate functions as sub-selects in FROM.  So it's probably
> not worth any effort to add more code to a routine that shouldn't exist
> in the first place; we've got to work on the fundamental problem
What makes me nervous is the fact, that I've seen limitations with
the length of the sql statements, some hidden problems here and there
and we want to use PostgreSQL in a research projects the next year
and we're writing now some oo->rdbms mapper software and therefore
we produce some "non-typical" statements and see those limitations
(and perhaps even better: some are not documented).
Marten


Re: [SQL] HAVING in EXISTS-clause ...

From
wieck@debis.com (Jan Wieck)
Date:
>
> Hello all out there,
>
> > involving aggregate functions as sub-selects in FROM.  So it's probably
> > not worth any effort to add more code to a routine that shouldn't exist
> > in the first place; we've got to work on the fundamental problem
>
>  What makes me nervous is the fact, that I've seen limitations with
> the length of the sql statements, some hidden problems here and there
> and we want to use PostgreSQL in a research projects the next year
> and we're writing now some oo->rdbms mapper software and therefore
> we produce some "non-typical" statements and see those limitations
> (and perhaps even better: some are not documented).

    Nervous or not, Tom is right!

    Some  people  seem  to  forget  that Postgres initially was a
    PostQUEL  database.  After  the  original  Berkeley   project
    terminated,  it  became  a SQL database and (sometimes) later
    called PostgreSQL.

    The PostQUEL query language was way simpler than SQL. All the
    internal structures of Postgres where optimized to match this
    language.

    We need to change a detail in  the  parser/rewriter  now,  to
    meet the needs of our new language. This requires changes not
    only in the parser and rewirter,  the  planner/optimizer  and
    maybe  the  executor need changes too.  Usually, this kind of
    vertical change takes some time in open source projects.

    But it doesn't help to continue doing cosmetic changes on the
    symptoms.  Sometimes you have to attack the initial problems,
    and this time is now.


Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#========================================= wieck@debis.com (Jan Wieck) #