2010-01-20 15 views
13

Diciamo che ho qualcosa di simile a questo:Riferendosi alle colonne dinamiche in una query postgres?

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

io sono in grado di fare riferimento a total_points nella clausola in cui perché ricevo il seguente errore: ERROR: column "total_points" does not exist. In questo caso non avrei problemi a riscrivere sum(points) nella clausola where, ma mi piacerebbe un modo per fare ciò che ho sopra.

  • C'è un modo per memorizzare il risultato in una variabile senza utilizzando una stored procedure?
  • Se io faccio riscrittura sum(points) nella clausola WHERE, è Postgres abbastanza intelligente da non ricalcolare esso?

risposta

7

credo PostgreSQL è come le altre marche di SQL, in cui è necessario fare:

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

EDIT: Ho dimenticato di alias sottoquery.

+0

No, Postgres supporta la clausola HAVING - vedi risposta di Quassnoi. –

+3

Mentre 'PostgreSQL' supporta la clausola' HAVING', anche questa è una risposta valida (eccetto che la subquery dovrebbe essere alias). Non vedo alcun motivo per fare downvoting. – Quassnoi

+0

@Quassnoi - Concordato. Sarei PIÙ usare l'HAVING per cose semplici, come 'SUM',' COUNT', ecc., Ma se sto facendo una funzione matematica prolissa per il mio alias, preferirei impostarlo in una sottoquery quindi la mia query sembra più pulita/più bella. –

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

PostgreSQL non calcolerà la somma due volte.

+0

Io non sono che la familiarità con PostgreSQL, ma mi piacerebbe pensare che sarebbe si lamentano perché il GROUP BY colonna non è nell'elenco SELECT . È qualcosa che PostgreSQL fa in modo diverso? –

+0

'@Bob Jarvis': nessun database di cui sono a conoscenza si lamenterà di una colonna' GROUP BY' non presente nell'elenco 'SELECT'. – Quassnoi

+3

che dovrebbe essere la risposta accettata. –

6

avete errore nella dichiarazione:

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

Non è possibile limitare le righe da total_points, perché sometable non hanno quella colonna. Quello che vuoi è limite gouped righe risultanti da total_points, calcolato per ogni gruppo, in modo da:

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

Se si sostituisce total_point nel tuo esempio, allora è sufficiente Chech se somma calcolata da tutte le file è più grande di 25 e poi di ritorno tutte le righe, raggruppate per nome utente.

Edit:
ordine Ricordate sempre:

  1. è FROM con JOIN 's per ottenere tabelle
  2. è WHERE per le righe limite da tabelle
  3. è SELECT per le colonne limite
  4. è GROUP BY per le righe di gruppo in gruppi correlati
  5. è HAVING per gruppi limite risultante
  6. è ORDER BY per risultati ordina
+0

'PostgreSQL' non consente alias nella clausola' HAVING'. – Quassnoi

+0

@quassnoi Non lo sapevo. È difficile che la maggior parte degli RDBMS accettino alias – MBO

+0

'@ MBO': dei quattro principali solo 'MySQL' consente questo. 'Oracle',' SQL Server' e 'PostgreSQL' non sono – Quassnoi