2012-09-06 6 views
11

ho la seguente domanda, che funziona alla grande in Postgres 9.1:Postgres caso al fine utilizzando un alias

SELECT users.id, GREATEST(
COALESCE(MAX(messages.created_at), '2012-07-25 16:05:41.870117'), 
COALESCE(MAX(phone_calls.created_at), '2012-07-25 16:05:41.870117') 
) AS latest_interaction 
FROM users LEFT JOIN messages ON users.id = messages.user_id 
LEFT JOIN phone_calls ON users.id = phone_calls.user_id 
GROUP BY users.id 
ORDER BY latest_interaction DESC 
LIMIT 5; 

Ma quello che voglio fare è qualcosa di simile:

SELECT users.id, GREATEST(
COALESCE(MAX(messages.created_at), '2012-07-25 16:05:41.870117'), 
COALESCE(MAX(phone_calls.created_at), '2012-07-25 16:05:41.870117') 
) AS latest_interaction 
FROM users LEFT JOIN messages ON users.id = messages.user_id 
LEFT JOIN phone_calls ON users.id = phone_calls.user_id 
GROUP BY users.id 
ORDER BY 
    CASE WHEN(
    latest_interaction > '2012-09-05 16:05:41.870117') 
    THEN 0 
    WHEN(latest_interaction > '2012-09-04 16:05:41.870117') 
    THEN 2 
    WHEN(latest_interaction > '2012-09-04 16:05:41.870117') 
    THEN 3 
    ELSE 4 
    END 
LIMIT 5; 

E io ottenere il seguente errore: ERRORE: colonna "latest_interaction" inesistente

Sembra che non sia possibile utilizzare l'alias per l'aggregato latest_interaction nell'ordine per clausola w con una dichiarazione CASE.

Esistono soluzioni alternative per questo?

risposta

19

Cercate di avvolgere come una sottoquery:

SELECT * 
FROM 
(
    SELECT users.id, 
     GREATEST(
      COALESCE(MAX(messages.created_at), '2012-07-25 16:05:41.870117'), 
      COALESCE(MAX(phone_calls.created_at), '2012-07-25 16:05:41.870117') 
     ) AS latest_interaction 
     FROM users LEFT JOIN messages ON users.id = messages.user_id 
     LEFT JOIN phone_calls ON users.id = phone_calls.user_id 
     GROUP BY users.id 
) Sub 
ORDER BY 
    CASE WHEN(
    latest_interaction > '2012-09-05 16:05:41.870117') 
    THEN 0 
    WHEN(latest_interaction > '2012-09-04 16:05:41.870117') 
    THEN 2 
    WHEN(latest_interaction > '2012-09-04 16:05:41.870117') 
    THEN 3 
    ELSE 4 
    END 
LIMIT 5; 
+0

Perfetto è esattamente quello che sto cercando! – dwilkie

+0

come sarebbe per l'ordine decrescente? pls ,,, ho provato ma il suo errore di sintassi! –

+0

@ X-Coder Basta usare 'CASE ... END DESC' –

2

Il manuale PG dice il ORDER BY espressione:

Each expression can be the name or ordinal number of an output column (SELECT list item), or it can be an arbitrary expression formed from input-column values.

La soluzione subquery da @Mahmoud funzionerà, oppure è possibile creare il ORDINA PER utilizzando le colonne originali messages.created_at o phone_calls.created_at