《Oracle SQL疑难解析》——1.14 排序

1.14 排序

Oracle SQL疑难解析

1.14.1 要解决的问题

我们的文本数据混合了大写、小写字母和句子(英文句子,指第一个字母大写,后续字母小写)。我们希望把这些数据按字母顺序、大小写顺序进行排列。

1.14.2 解决方法

我们先在HR.EMPLOYEES表中创建一些混合大小写的数据。运行下面的UPDATE语句,把William Smith's的姓(last_name)改为大写:

update hr.employees
set last_name = 'SMITH'
where employee_id = 171;

下面的select语句要求按Oracle默认的排序方式显示根据last_name排序的结果:

select last_name
from hr.employees
order by last_name;
LAST_NAME
---------
…
Rogers
Russell
SMITH
Sarchand
Sciarra
Seo
Sewall
Smith
Stiles
Sullivan
…

聪明的读者可能已经猜到了排序结果。Oracle默认用二进制的排序方法。在上面这个简单的例子中,文本是按它们在代码页上对应数值的大小来排列的。编码可以是US7ASCII,WEIISO8859P1或其他编码方式。在这些代码页上,大、小写字母有不同的值,大写的值排在前面。这就是为什么上面查询结果中SMITH排在所有以“S”开头的姓的最前面。

人们通常希望看见两个“Smith”排在一起,忽略大小写。用这个NLS环境变量可以达到目的:

alter session set NLS_SORT='BINARY_CI';

select last_name
from hr.employees
order by last_name;
LAST_NAME
---------
…
Rogers
Russell
Sarchand
Sciarra
Seo
Sewall
Smith
SMITH
Stiles
Sullivan
…

1.14.3 数据库如何工作

Oracle支持区分大小写和不区分大小写两种排序方式。有个环境变量NLS_SORT进行区分大小写和不区分大小写的控制。默认的排序操作区分大小写,即NLS_SORT=BINARY。如果我们希望排序按照不区分大小写的方式,则需把环境变量NLS_SORT设置为BINARY_CI。

顾名思义,NLS_SORT仅仅影响排序结果,并不对其他大小写操作构成影响。即使把NLS_SORT设置为BINARY_CI,以不区分大小写的方式比较数据的操作仍然延续了Oracle默认的方式:

select first_name, last_name
from hr.employees
where last_name like 's%';
no rows selected

对以上结果别灰心。Oracle想到了你的需求,也提供了不区分大小写的比较方式。

比较传统的方式不是使用NLS环境变量,而是用UPPER和LOWER函数把要比较的字段名、文字都转成大写或小写后再比较。这种方法的不足之处在于,使用函数后,标准的索引就不能使用了,优化器无法工作,应对的方式是使用基于功能的索引(function-based index)。

时间: 2024-09-20 05:56:40

《Oracle SQL疑难解析》——1.14 排序的相关文章

《Oracle SQL疑难解析》——1.15 启用其他排序和比较选项

1.15 启用其他排序和比较选项 Oracle SQL疑难解析 1.15.1 要解决的问题 文本数据由大.小写字母和句子(英文句子,指第一个字母大写,后续字母小写)组成,我们希望对之进行不区分大小写的比较.排序等操作. 1.15.2 解决方法激活Oracle的语言比较逻辑,就能按人类的习惯来查询数据,摆脱大小写负担: alter session set NLS_COMP='LINGUISTIC'; select first_name, last_name from hr.employees wh

《Oracle SQL疑难解析》——1.3 将结果排序

1.3 将结果排序 Oracle SQL疑难解析 1.3.1 要解决的问题 用户想把查询出来的记录按某种顺序排列.例如,他们想把员工先按姓.再按名的字母顺序排列. 1.3.2 解决方法 Oracle允许使用标准的ORDER BY子句来排列查询结果: select employee_id, first_name, last_name, hire_date, salary from hr.employees where salary > 5000 order by last_name, first_

《Oracle SQL疑难解析》导读

前言 Oracle SQL疑难解析 欢迎阅读本书.现在你手中的这本书,对在Oracle数据库中编写SQL时经常碰到的问题提供了现成的解决方法.这本书写给那些迫切需要解决某个特定问题的人.本书每一节讨论一个特定的问题,并为这一问题提供了一个有效的解决方法.对于解决方法感兴趣的人,每一节还扩展讨论了解决方法,有些还提供了替代解决方法. 我们精心编写了这本书,是为了让你掌握如何为Oracle编写SQL,至少可以让你了解Oracle的SQL.虽然我们把内容分割成有逻辑的章节,例如,数据类型或生成报表,但

《Oracle SQL疑难解析》——1.1 从表中查询数据

1.1 从表中查询数据 Oracle SQL疑难解析 1.1.1 要解决的问题 如何从一个表中查询特定行和列的数据. 1.1.2 解决方法 用包含WHERE子句的SELECT语句.下面的SELECT 语句可以从数据库表中查询符合条件的行的列值: select employee_id, first_name, last_name, hire_date, salary from hr.employees where department_id = 50 and salary < 7500; 上述SE

《Oracle SQL疑难解析》——.13 在语句中找到和消除空值

1.13 在语句中找到和消除空值 Oracle SQL疑难解析 1.13.1 要解决的问题 我们需要统计出公司中,有多少员工的薪酬里含销售提成(commission percentage),有多少员工的薪酬是固定工资.我们可以用HR.EMPLOYEES表中的COMMISSION_PCT字段来获得数据. 1.13.2 解决方法 HR.EMPLOYEES表的结构允许COMMISSION_PCT字段为空值.有两个查询语句可以分别查找commission percent为空值的人和为非空值的人.首先,查

《Oracle SQL疑难解析》——1.12 查询的WHERE子句基于另一个查询的结果

1.12 查询的WHERE子句基于另一个查询的结果 Oracle SQL疑难解析 1.12.1 要解决的问题 我们要从某张表中查询数据,但查询条件依赖当时另一张表中的数据情况,所以不能直接把条件固定到语句中.具体地说,我们现在要做一个报告,把所有办公场所在北美的部门列出来. 1.12.2 解决方法 在HR SCHEMA中,DEPARTMENT表中有部门的信息,LOCATIONS表中有办公场所的信息: select department_name from hr.departments where

《Oracle SQL疑难解析》——第1章 基础

第1章 基础 Oracle SQL疑难解析本章针对SQL语句的核心构建模块,罗列了很多的基本操作诀窍,以便让初学者快速上手,或者让有经验的读者重温技术关键点.本章主要内容包括对Oracle数据库表中数据的查询.更改.删除,以及进行此类操作时需要输入的一些常用的选项. 对那些已有很好SQL基础的人员,我们建议选择性地翻阅本章,仅看你感兴趣的章节,而不是全盘通读.为节约读者的时间,我们在本章的一开头,就列出了一两个精华的操作指导,这样你只需花很少的时间,就能掌握关键内容.你也可以把本章学到的内容和后

《Oracle SQL疑难解析》——1.2 把表中所有字段都列出来

1.2 把表中所有字段都列出来 Oracle SQL疑难解析 1.2.1 要解决的问题 我们要把表中所有的字段数据都列出来,但并不想把每个字段名都在SELECT后面输入一遍. 1.2.2 解决方法 使用星号(*)占位符,即可代表所有表中字段,例如: select * from hr.employees where department_id = 50 and salary < 7500; ``` 因为列多页窄,查询结果换行显示,为节省空间,我们也仅仅在下面列了几行,但相信你已经能看出来用"

《Oracle SQL疑难解析》——1.6 批量地从一个表中复制数据到另一个表

1.6 批量地从一个表中复制数据到另一个表 Oracle SQL疑难解析 1.6.1 要解决的问题 如何从一个表中一次性复制多行记录到另一个表. 1.6.2 解决方法 INSERT INTO... SELECT... 方法可以插入多行记录,关键是用SELECT语句选择多行记录时一定要用对选择条件.我们把以前的SELECT语句做一点修改,就可以选择多行记录了: 当然,前提是存在HR.CANDIDATES表,在做练习前,应确保你的HR.CANDIDATES表和例子中的表是一致的. 1.6.3 数据库