How to have a custom sort order for a union query in Postgres

邮差的信 提交于 2019-12-09 15:09:58

问题


With a query like this (simplified for clarity):

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'

I want to customise the order of the resulting rows. Something like:

ORDER BY name='East', name='West', name='Both'

Or

ORDER BY 
    CASE
        WHEN name='East' THEN 1 
        WHEN name='West' THEN 2
        WHEN name='Both' THEN 3
        ELSE 4
    END;

However, Postgres complains with:

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.

Do I have any alternative?


回答1:


Wrap it in a derived table (which is what "HINT: .... or move the UNION into a FROM clause" is suggesting)

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;



回答2:


I'd add an extra column showing the desired ordering, then use ordinal column positions in the ORDER BY, e.g.

SELECT 1, 'East' AS name, *
...
UNION ALL
SELECT 2, 'West' AS name, *
...
ORDER BY 1

Note that you probably also want UNION ALL since your added columns ensure that every set in the union must be distinct anyway.




回答3:


By adding an extra column for ordering purpose, however it makes the UNION clause to work exactly as a UNION ALL (it does not eliminate duplicate rows from the result).



来源:https://stackoverflow.com/questions/31023565/how-to-have-a-custom-sort-order-for-a-union-query-in-postgres

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!