tags:

views:

67

answers:

3

Let's say I have something like this:

select sum(points) as total_points
from sometable
where total_points > 25
group by username

I am unable to refer to total_points in the where clause because I get the following error: ERROR: column "total_points" does not exist. In this case I'd have no problem rewriting sum(points) in the where clause, but I'd like some way of doing what I have above.

  • Is there any way to store the result in a variable without using a stored procedure?
  • If I do rewrite sum(points) in the where clause, is postgres smart enough to not recalculate it?
+5  A: 
SELECT  SUM(points) AS total_points
FROM    sometable
GROUP BY
        username
HAVING  SUM(points) > 25

PostgreSQL won't calculate the sum twice.

Quassnoi
I'm not that familiar with PostgreSQL, but I'd think it would complain because the GROUP BY column isn't in the SELECT list. Is this something PostgreSQL does differently?
Bob Jarvis
`@Bob Jarvis`: no database I'm aware of will complain about a `GROUP BY` column not being in the `SELECT` list.
Quassnoi
+3  A: 

I believe PostgreSQL is like other brands of sql, where you need to do:

SELECT t.* 
FROM (
    SELECT SUM(points) AS total_points
    FROM sometable
    GROUP BY username
) t
WHERE total_points > 25

EDIT: Forgot to alias subquery.

md5sum
No, Postgres does support the HAVING clause - see answer by Quassnoi.
Bandi-T
While `PostgreSQL` does support the `HAVING` clause, this is a valid answer too (except that the subquery should be aliased). See no reason for downvoting it.
Quassnoi
@Quassnoi - Agreed. I would RATHER use the `HAVING` for simple things, such as `SUM`, `COUNT`, etc., but if I'm doing some long-winded mathematical function for my alias, I'd rather set it in a subquery so my query looks cleaner/nicer.
md5sum
@Bandi-T - My answer offers the only method to refer directly to the alias, where using the `HAVING` clause would require repeating the function. I do realize that the function wouldn't be recalculated, but sometimes referencing the alias makes a query MUCH more readable.
md5sum
Ok, I bow to you. Downvote removed.
Bandi-T
+3  A: 

You have error in statement:

select sum(points) as total_points
from sometable
where total_points > 25 -- <- error here
group by username

You can't limit rows by total_points, because sometable don't have that column. What you want is limit gouped resulting rows by total_points, computed for each group, so:

select sum(points) as total_points
from sometable
group by username
having sum(points) > 25

If you replace total_point in your example, then you simply chech if sum computed from all rows is bigger than 25 and then return all rows, grouped by username.

Edit:
Always remember order:

  1. is FROM with JOIN's to get tables
  2. is WHERE for limit rows from tables
  3. is SELECT for limit columns
  4. is GROUP BY for group rows into related groups
  5. is HAVING for limit resulting groups
  6. is ORDER BY for order results
MBO
`PostgreSQL` does not allow aliases in the `HAVING` clause.
Quassnoi
@quassnoi I didn't know that. I tough that most RDBMS-es accept aliases
MBO
`@MBO`: of the major four only `MySQL` allows this. `Oracle`, `SQL Server` and `PostgreSQL` don't
Quassnoi
@quassnoi Sqlite3 also supports aliases. That's where my mistake came from - i tought sqlite tries to mimic much of postgresql features and not add its own :-)
MBO