如何在 Postgres 中为联合查询自定义排序顺序
How to have a custom sort order for a union query in Postgres
使用这样的查询(为清楚起见进行了简化):
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'
我想自定义结果行的顺序。类似于:
ORDER BY name='East', name='West', name='Both'
或者
ORDER BY
CASE
WHEN name='East' THEN 1
WHEN name='West' THEN 2
WHEN name='Both' THEN 3
ELSE 4
END;
但是,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.
我有其他选择吗?
将其包装在派生的 table 中(这就是“提示:....或将 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;
我会添加一个额外的列来显示所需的顺序,然后在 ORDER BY
中使用序数列位置,例如
SELECT 1, 'East' AS name, *
...
UNION ALL
SELECT 2, 'West' AS name, *
...
ORDER BY 1
请注意,您可能还需要 UNION ALL
,因为您添加的列确保并集中的每个集合无论如何都必须不同。
通过添加一个额外的列用于排序目的,但是它使 UNION 子句与 UNION ALL 完全一样工作(它不会从结果中消除重复的行)。
使用这样的查询(为清楚起见进行了简化):
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'
我想自定义结果行的顺序。类似于:
ORDER BY name='East', name='West', name='Both'
或者
ORDER BY
CASE
WHEN name='East' THEN 1
WHEN name='West' THEN 2
WHEN name='Both' THEN 3
ELSE 4
END;
但是,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.
我有其他选择吗?
将其包装在派生的 table 中(这就是“提示:....或将 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;
我会添加一个额外的列来显示所需的顺序,然后在 ORDER BY
中使用序数列位置,例如
SELECT 1, 'East' AS name, *
...
UNION ALL
SELECT 2, 'West' AS name, *
...
ORDER BY 1
请注意,您可能还需要 UNION ALL
,因为您添加的列确保并集中的每个集合无论如何都必须不同。
通过添加一个额外的列用于排序目的,但是它使 UNION 子句与 UNION ALL 完全一样工作(它不会从结果中消除重复的行)。