多重排序是生成报告时的重要工具,当需要根据多个列(例如,首先按日期,随后按名字,再之后按金额)对数据进行排名或分组时尤为重要。传统上,排序仅限于单个字段,这并不能解决复杂的数据分析问题。
问题通常出现在排序顺序不正确(例如,NULL 值位置意外)、排序规则错误(不同语言的字符串值排序规则)和在大型数据集上性能降低。
解决方案: 使用多列的 ORDER BY,考虑 COLLATION 特性并明确指定 NULLS 的顺序以确保结果的确定性,同时检查大型表的列索引。
示例代码:
SELECT * FROM sales ORDER BY region COLLATE "ru_RU", date DESC NULLS LAST, total_amount DESC;
关键特性:
如果不指定 COLLATE,排序在不同服务器上是否总是相同?
不!默认的 COLLATE 依赖于数据库和/或服务器的设置,结果的字符串排序(特别是用西里尔字母和特殊字符)在不同的安装中可能会有所不同。
在 DESC 和 ASC 排序时,NULL 会放在哪里?
SQL 标准并未明确规定。在某些数据库管理系统中,NULL 在 ASC 排序时位于顶部,而在其他系统中位于底部。明确指出 NULLS FIRST 或 NULLS LAST 以使行为透明。
ORDER BY price DESC NULLS LAST
在多个列上使用 ORDER BY 是否会影响使用索引?
是的,但仅当列的顺序、类型与现有的复合索引相符时。如果顺序混合(ASC/DESC)或使用了计算字段,则可能不会使用索引。
经理创建了一个按姓氏排序的报告,未指定 COLLATE。当在不同服务器间迁移报告时,俄文和拉丁姓氏互换位置,NULL 值有时在开头,有时在结尾。
优点:
在报告中明确指定了 COLLATE 和 NULL 的顺序,通过 NULLS FIRST/LAST,添加了排序字段的复合索引。行为不再依赖于环境,查询速度显著提高。
优点: