2010-01-20 31 views
13

Digamos que tengo algo como esto:¿Haciendo referencia a columnas dinámicas en una consulta postgres?

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

Soy incapaz de hacer referencia a total_points en la cláusula where porque me sale el siguiente error: ERROR: column "total_points" does not exist. En este caso, no tendría problemas para volver a escribir sum(points) en la cláusula where, pero me gustaría tener alguna forma de hacer lo que tengo arriba.

  • ¿Hay alguna manera de almacenar el resultado en una variable y sin el uso de un procedimiento almacenado?
  • Si do reescribe sum(points) en la cláusula where, ¿es postgres lo suficientemente inteligente como para no volver a calcularlo?

Respuesta

7

creo PostgreSQL es como otras marcas de SQL, en las que tiene que hacer:

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

EDIT: se olvidó de subconsulta alias.

+0

No, Postgres admite la cláusula HAVING - ver respuesta de Quassnoi. –

+3

Si bien 'PostgreSQL' admite la cláusula' HAVING', esta también es una respuesta válida (excepto que la subconsulta debe tener un alias). No veo razón para revocarla. – Quassnoi

+0

@Quassnoi - De acuerdo. RATARÍA usar el 'HAVING' para cosas simples, como' SUM', 'COUNT', etc., pero si estoy haciendo una función matemática prolija para mi alias, preferiría establecerla en una subconsulta entonces mi consulta se ve más limpia/más agradable. –

17
SELECT SUM(points) AS total_points 
FROM sometable 
GROUP BY 
     username 
HAVING SUM(points) > 25 

PostgreSQL no calculará la suma dos veces.

+0

No soy tan familiarizados con PostgreSQL, pero yo pensaría que se quejaba porque la columna GROUP BY no está en la lista SELECT . ¿Esto es algo que PostgreSQL hace de manera diferente? –

+0

'@Bob Jarvis': ninguna base de datos de la que tenga conocimiento se quejará de que una columna' GROUP BY' no esté en la lista 'SELECT'. – Quassnoi

+3

que debería ser la respuesta aceptada. –

6

usted tiene error en la declaración:

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

No se puede limitar filas por total_points, porque sometable no tienen esa columna. Lo que queremos es límite gouped filas resultantes por total_points, calculada para cada grupo, por lo que:

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

Si reemplaza total_point en su ejemplo, entonces simplemente Entrada si suma calculada a partir de todas las filas es mayor que 25 y luego de retorno todas las filas, agrupadas por nombre de usuario.

Editar:
Siempre recuerda orden:

  1. es FROM con JOIN 's para obtener tablas
  2. es WHERE para las filas límite de las tablas
  3. es SELECT para columnas límite
  4. es GROUP BY para filas de grupos en grupos relacionados
  5. es HAVING para grupos límite resultante
  6. es ORDER BY resultados Ordena
+0

'PostgreSQL' no permite alias en la cláusula' HAVING'. – Quassnoi

+0

@quassnoi No lo sabía. Me cuesta que la mayoría de RDBMS-es acepte los alias – MBO

+0

'@ MBO': de los cuatro principales, solo' MySQL' lo permite. 'Oracle',' SQL Server' y 'PostgreSQL' no – Quassnoi

Cuestiones relacionadas