Thread: HAVING in EXISTS-clause ...
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
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
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
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
> > 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) #