18

我有以下在 Postgres 9.1 中运行良好的查询:

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;

但我想做的是这样的:

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;

我收到以下错误:错误:列“latest_interaction”不存在

似乎我不能在 order by 子句中使用聚合 latest_interaction 的别名和 CASE 语句。

有什么解决方法吗?

4

2 回答 2

34

尝试将其包装为子查询:

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;
于 2012-09-06T10:52:58.293 回答
4

PG 手册说ORDER BY表达式:

每个表达式可以是输出列(SELECT 列表项)的名称或序号,也可以是由输入列值形成的任意表达式。

@Mahmoud 的子查询解决方案将起作用,或者您可以使用原始列messages.created_atphone_calls.created_at创建ORDER BY

于 2012-09-06T10:57:50.953 回答