排序 BY 子句
描述
用于返回按用户指定顺序在每个分区内排序的结果行的
SORT BY
子句。当有多个分区时,
SORT BY
可能返回部分排序的结果。这与保证输出的完全排序的
ORDER BY
子句不同。
语法
SORT BY { expression [ sort_direction | nulls_sort_order ] [ , ... ] }
参数
-
排序依据
指定一个逗号分隔的表达式列表,以及可选参数
sort_direction
和nulls_sort_order
,用于在每个分区内对行进行排序。 -
sort_direction
可选地指定是否按升序或降序排序行。排序方向的有效值是
ASC
表示升序 和DESC
表示降序。如果未明确指定排序方向,则默认为 升序排序。语法:
[ ASC | DESC ]
-
nulls_sort_order
可选地指定 NULL 值是在非 NULL 值之前还是之后返回。如果
null_sort_order
未指定,则如果排序顺序为ASC
,NULL 值最先排序;如果排序顺序为DESC
,NULL 值最后排序。-
如果
NULLS FIRST
被指定,则 NULL 值将首先返回 无论排序顺序如何。 -
如果
NULLS LAST
被指定,则 NULL 值将最后返回无论 排序顺序如何。
语法:
[ NULLS { FIRST | LAST } ]
-
如果
示例
CREATE TABLE person (zip_code INT, name STRING, age INT);
INSERT INTO person VALUES
(94588, 'Zen Hui', 50),
(94588, 'Dan Li', 18),
(94588, 'Anil K', 27),
(94588, 'John V', NULL),
(94511, 'David K', 42),
(94511, 'Aryan B.', 18),
(94511, 'Lalit B.', NULL);
-- 使用 `REPARTITION` 提示按 `zip_code` 划分数据,以便
-- 检查 `SORT BY` 行为。这在其余的
-- 示例中使用。
-- 按照升序在每个分区内根据 `name` 排序
SELECT /*+ REPARTITION(zip_code) */ name, age, zip_code FROM person SORT BY name;
+--------+----+--------+
| name| age|zip_code|
+--------+----+--------+
| Anil K| 27| 94588|
| Dan Li| 18| 94588|
| John V|null| 94588|
| Zen Hui| 50| 94588|
|Aryan B.| 18| 94511|
| David K| 42| 94511|
|Lalit B.|null| 94511|
+--------+----+--------+
-- 使用列位置在每个分区内对行进行排序。
SELECT /*+ REPARTITION(zip_code) */ name, age, zip_code FROM person SORT BY 1;
+--------+----+--------+
| name| age|zip_code|
+--------+----+--------+
| Anil K| 27| 94588|
| Dan Li| 18| 94588|
| John V|null| 94588|
| Zen Hui| 50| 94588|
|Aryan B.| 18| 94511|
| David K| 42| 94511|
|Lalit B.|null| 94511|
+--------+----+--------+
-- 在每个分区内按升序排序行,空值排在最后。
SELECT /*+ REPARTITION(zip_code) */ age, name, zip_code FROM person SORT BY age NULLS LAST;
+----+--------+--------+
| age| name|zip_code|
+----+--------+--------+
| 18| Dan Li| 94588|
| 27| Anil K| 94588|
| 50| Zen Hui| 94588|
|null| John V| 94588|
| 18|Aryan B.| 94511|
| 42| David K| 94511|
|null|Lalit B.| 94511|
+----+--------+--------+
-- 在每个分区内按年龄降序排序,默认空值在最后。
SELECT /*+ REPARTITION(zip_code) */ age, name, zip_code FROM person SORT BY age DESC;
+----+--------+--------+
| age| name|zip_code|
+----+--------+--------+
| 50| Zen Hui| 94588|
| 27| Anil K| 94588|
| 18| Dan Li| 94588|
|null| John V| 94588|
| 42| David K| 94511|
| 18|Aryan B.| 94511|
|null|Lalit B.| 94511|
+----+--------+--------+
-- 在每个分区内按年龄降序排序,空值排在最前。
SELECT /*+ REPARTITION(zip_code) */ age, name, zip_code FROM person SORT BY age DESC NULLS FIRST;
+----+--------+--------+
| age| name|zip_code|
+----+--------+--------+
|null| John V| 94588|
| 50| Zen Hui| 94588|
| 27| Anil K| 94588|
| 18| Dan Li| 94588|
|null|Lalit B.| 94511|
| 42| David K| 94511|
| 18|Aryan B.| 94511|
+----+--------+--------+
-- 在每个分区内根据多个列进行排序,每列具有
-- 不同的排序方向。
SELECT /*+ REPARTITION(zip_code) */ name, age, zip_code FROM person
SORT BY name ASC, age DESC;
+--------+----+--------+
| name| age|zip_code|
+--------+----+--------+
| Anil K| 27| 94588|
| Dan Li| 18| 94588|
| John V|null| 94588|
| Zen Hui| 50| 94588|
|Aryan B.| 18| 94511|
| David K| 42| 94511|
|Lalit B.|null| 94511|
+--------+----+--------+