如何在Postgres中为联合查询设置自定义排序顺序

Dav*_*ave 12 postgresql union sql-order-by

使用这样的查询(为简洁起见,简化):

SELECT 'East' AS name, *
FROM events 
WHERE event_timestamp BETWEEN '2015-06-14 06:15:00' AND '2015-06-21 06:15:00' 

UNION

SELECT 'West' AS name, *
FROM events 
WHERE event_timestamp BETWEEN '2015-06-14 06:15:00' AND '2015-06-21 06:15:00'

UNION

SELECT 'Both' AS name, *
FROM events 
WHERE event_timestamp BETWEEN '2015-06-14 06:15:00' AND '2015-06-21 06:15:00'
Run Code Online (Sandbox Code Playgroud)

我想自定义结果行的顺序.就像是:

ORDER BY name='East', name='West', name='Both'
Run Code Online (Sandbox Code Playgroud)

要么

ORDER BY 
    CASE
        WHEN name='East' THEN 1 
        WHEN name='West' THEN 2
        WHEN name='Both' THEN 3
        ELSE 4
    END;
Run Code Online (Sandbox Code Playgroud)

然而,Postgres抱怨说:

ERROR:  invalid UNION/INTERSECT/EXCEPT ORDER BY clause
DETAIL:  Only result column names can be used, not expressions or functions.
HINT:  Add the expression/function to every SELECT, or move the UNION into a FROM clause.
Run Code Online (Sandbox Code Playgroud)

我还有其他选择吗?

a_h*_*ame 23

将它包装在派生表中(这是" 提示:......或将UNION移动到FROM子句中 "建议)

select *
from (
  ... your union goes here ... 
) t
order by
    CASE
        WHEN name='East' THEN 1 
        WHEN name='West' THEN 2
        WHEN name='Both' THEN 3
        ELSE 4
    END;
Run Code Online (Sandbox Code Playgroud)


Cra*_*ger 13

我将添加一个显示所需排序的额外列,然后使用序数列位置ORDER BY,例如

SELECT 1, 'East' AS name, *
...
UNION ALL
SELECT 2, 'West' AS name, *
...
ORDER BY 1
Run Code Online (Sandbox Code Playgroud)

请注意,您可能也想要,UNION ALL因为添加的列确保联合中的每个集合都必须是不同的.