查询结果中有NULL值,当进行升序排序时,NULL值默认为“最大值”,排在最后面。要想改变NULL值的显示顺序,只需要在SQL语句后面加上NULLS FIRST(排在前面),NULLS LAST(排在后面)。
1)升序排列,NUll值排在前面
SQL> SELECT DISTINCT department_id FROM employees ORDER BY 1 NULLS FIRST;
DEPARTMENT_ID
-------------
12 rows selected.
2)降序排列,NULL值排在后面
SQL> SELECT DISTINCT department_id FROM employees ORDER BY 1 DESC NULLS LAST;
DEPARTMENT_ID
-------------
12 rows selected.
查询结果中有NULL值,当进行升序排序时,NULL值默认为“最大值”,排在最后面。要想改变NULL值的显示顺序,只需要在SQL语句后面加上NULLS FIRST(排在前面),NULLS LAST(排在后面)。例如:1)升序排列,NUll值排在前面SQL> SELECT DISTINCT department_id FROM employees ORDER BY 1 NULLS FI
《
SQL
Server 2008宝典》全面介绍了
SQL
Server 2008各方面的知识,全书由6部分组成:第1部分为数据库的基础篇,介绍了数据库的类型、概念、对象、
SQL
语言等;第2部分为
SQL
Server 2008的准备篇,介绍了
SQL
Server 2008的功能、特性、各版本的比较、安装方法、
SQL
Server 2008的服务、客户端的工具等;第3部分为
SQL
Server 2008的基本操作篇,介绍如何管理与配置
SQL
Server 2008服务器、如何创建数据库和数据表、如何对数据库里的数据进行操作;第4部分为数据库管理篇,介绍如何使用T-
SQL
程序对数据进行复杂的运算,以及如何使用视图、存储过程、触发器、索引、用户定义数据类型、用户定义函数、全文索引、游标、事务和锁、统计信息和同义词等方面的知识;第5部分为
SQL
Server高级技术,介绍如何进行数据库备份与恢复、如何规划数据库、如何保证数据库的安全、复制与发布、自动化管理、如何使用性能工具优化数据库、数据的导入导出、
SQL
Server邮件的使用、Analysis Services、Reporting Services、
SQL
Server与XML的应用,以及如何使用客户端和应用程序访问
SQL
Server;第6部分为
SQL
Server 2008改进篇,介绍了
SQL
Server 2008相对于之前版本进行了哪些方面的重大改进和优化,进一步帮助读者了解
SQL
Server 2008更多的独有特性。
《
SQL
Server 2008宝典》适合
SQL
Server 2008的初学者学习,也适合子数据库的管理人员和开发人员阅读和参考。
《
SQL
Server 2008宝典》:实例丰富,内容充实。书中针对每一个知识点列举了大量实例来说明该功能如何实现,全书共有超过500个精彩实例。
讲解通俗,步骤详细。通过通俗易懂的语言讲解
SQL
Server 2008的各个强大功能,并配以插图讲解和详细的步骤说明,帮助读者快速掌握实用技能。
由浅入深,难易穿插。《
SQL
Server 2008宝典》面向入门级和提高级两类读者,每个知识点都采用由浅入深的讲解方式,并穿插介绍重点和难点。
提供源码,方便学习。书中涉及到的T—
SQL
程序在网站上提供下载,打开相应
SQL
文件即可直接执行其中的代码。
SQL
Server 2008是一个能用于大型联机事务处理、数据仓库和电子商务等方面应用的数据库平台,也是一个能用于数据集成、数据分析和报表解决方案的商业智能平台,为用户提供了强大、集成、便于使用的工具,使系统管理员与普通用户能更方便、更快捷地管理数据库或设计、开发应用程序。
封面 -33
封底 803
扉页 -32
版权 -31
前言 -30
目录 -26
第1部分 基础篇 1
第1章 认识数据库 2
1.1 数据库的类型 2
1.1.1 结构型数据库 2
1.1.2 网络型数据库 2
1.1.3 关系型数据库 2
1.1.4 面向对象型数据库 3
1.2 数据库的基本概念 3
1.2.1 数据 3
1.2.2 数据库 3
1.2.3 数据库管理系统 3
1.2.4 数据库系统 3
1.3 常见的数据库对象 3
1.3.1 表与记录 4
1.3.2 主键与外键 4
1.3.3 索引 4
1.3.4 约束 5
1.3.5 视图 5
1.3.6 关系图 5
1.3.7 默认
值
5
1.3.8 规则 5
1.3.9 存储过程 6
1.3.10 触发器 6
1.3.11 用户和角色 6
1.4 数据库管理系统的基本功能 6
1.4.1 定义数据 6
1.4.2 处理数据 6
1.4.3 保证数据安全 6
1.4.4 备份和恢复数据 6
1.5
SQL
语言简介 6
1.5.1
SQL
语言的历史 7
1.5.2
SQL
语言的优点 7
1.5.3
SQL
语言分
一、问题的提出
在应用系统开发初期,由于开发数据库数据比较少,对于查询
SQL
语句,复杂视图的的编写等体会不出
SQL
语句各种写法的性能优劣,但是如果将应用系统提交实际应用后,随着数据库中数据的增加,系统的响应速度就成为目前系统需要解决的最主要的问题之一。系统优化中一个很重要的方面就是
SQL
语句的优化。对于海量数据,劣质
SQL
语句和优质
SQL
语句之间的速度差别可以达到上百倍,可见对于一个系统不是简单地能实现其功能就可,而是要写出高质量的
SQL
语句,提高系统的可用性。
在多数情况下,Oracle使用索引来更快地遍历表,优化器主要根据定义的索引来提高性能。但是,如果在
SQL
语句的where子句中写的
SQL
代码不合理,就会造成优化器删去索引而使用全表扫描,一般就这种
SQL
语句就是所谓的劣质
SQL
语句。在编写
SQL
语句时我们应清楚优化器根据何种原则来删除索引,这有助于写出高性能的
SQL
语句。
二、
SQL
语句编写注意问题
下面就某些
SQL
语句的where子句编写中需要注意的问题作详细介绍。在这些where子句中,即使某些列存在索引,但是由于编写了劣质的
SQL
,系统在运行该
SQL
语句时也不能使用该索引,而同样使用全表扫描,这就造成了响应速度的极大降低。
1. IS
NULL
与 IS NOT
NULL
不能用
null
作索引,任何包含
null
值
的列都将不会被包含在索引中。即使索引有多列这样的情况下,只要这些列中有一列
含有
null
,该列就会从索引中排除。也就是说如果某列存在空
值
,即使对该列建索引也不会提高性能。
任何在where子句中使用is
null
或is not
null
的语句优化器是不允许使用索引的。
2. 联接列
对于有联接的列,即使最后的联接
值
为一个静态
值
,优化器是不会使用索引的。我们一起来看一个例子,假定有一个职工表(employee),对于一个职工的姓和名分成两列存放(FIRST_NAME和LAST_NAME),现在要查询一个叫比尔.克林顿(Bill Cliton)的职工。
下面是一个采用联接查询的
SQL
语句,
select * from employss where first_name||''||last_name ='Beill Cliton';
上面这条语句完全可以查询出是否有Bill Cliton这个员工,但是这里需要注意,系统优化器对基于last_name创建的索引没有使用。
当采用下面这种
SQL
语句的编写,Oracle系统就可以采用基于last_name创建的索引。
*** where first_name ='Beill' and last_name ='Cliton';
. 带通配符(%)的like语句
同样以上面的例子来看这种情况。目前的需求是这样的,要求在职工表中查询名字中包含cliton的人。可以采用如下的查询
SQL
语句:
select * from employee where last_name like '%cliton%';
这里由于通配符(%)在搜寻词首出现,所以Oracle系统不使用last_name的索引。在很多情况下可能无法避免这种情况,但是一定要心中有底,通配符如此使用会降低查询速度。然而当通配符出现在字符串其他位置时,优化器就能利用索引。在下面的查询中索引得到了使用:
select * from employee where last_name like 'c%';
4. Order by语句
ORDER BY语句决定了Oracle如何将返回的查询结果
排序
。Order by语句对要
排序
的列没有什么特别的限制,也可以将函数加入列中(象联接或者附加等)。任何在Order by语句的非索引项或者有计算表达式都将降低查询速度。
仔细检查order by语句以找出非索引项或者表达式,它们会降低性能。解决这个问题的办法就是重写order by语句以使用索引,也可以为所使用的列建立另外一个索引,同时应绝对避免在order by子句中使用表达式。
5. NOT
我们在查询时经常在where子句使用一些逻辑表达式,如大于、小于、等于以及不等于等等,也可以使用and(与)、or(或)以及not(非)。NOT可用来对任何逻辑运算符号取反。下面是一个NOT子句的例子:
... where not (status ='VALID')
如果要使用NOT,则应在取反的短语前面加上括号,并在短语前面加上NOT运算符。NOT运算符包含在另外一个逻辑运算符中,这就是不等于(<>)运算符。换句话说,即使不在查询where子句中显式地加入NOT词,NOT仍在运算符中,见下例:
... where status <>'INVALID';
对这个查询,可以改写为不使用NOT:
select * from employee where salary<3000 or salary>3000;
虽然这两种查询的结果一样,但是第二种查询方案会比第一种查询方案更快些。第二种查询允许Oracle对salary列使用索引,而第一种查询则不能使用索引。
虽然这两种查询的结果一样,但是第二种查询方案会比第一种查询方案更快些。第二种查询允许Oracle对salary列使用索引,而第一种查询则不能使用索引。
===============================================================================================
我们要做到不但会写
SQL
,还要做到写出性能优良的
SQL
,以下为笔者学习、摘录、并汇总部分资料与大家分享!
(1) 选择最有效率的表名顺序(只在基于规则的优化器中有效):
ORACLE 的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表.
(2) WHERE子句中的连接顺序.:
ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾.
(3) SELECT子句中避免使用 ‘ * ‘:
ORACLE在解析的过程中, 会将'*' 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间
(4) 减少访问数据库的次数:
ORACLE在内部执行了许多工作: 解析
SQL
语句, 估算索引的利用率, 绑定变量 , 读数据块等;
(5) 在
SQL
*Plus ,
SQL
*Forms和Pro*C中重新设置ARRAYSIZE参数, 可以增加每次数据库访问的检索数据量 ,建议
值
为200
(6) 使用DECODE函数来减少处理时间:
使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表.
(7) 整合简单,无关联的数据库访问:
如果你有几个简单的数据库查询语句,你可以把它们整合到一个查询中(即使它们之间没有关系)
(8) 删除重复记录:
最高效的删除重复记录方法 ( 因为使用了ROWID)例子:
DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID)
FROM EMP X WHERE X.EMP_NO = E.EMP_NO);
(9) 用TRUNCATE替代DELETE:
当删除表中的记录时,在通常情况下, 回滚段(rollback segments ) 用来存放可以被恢复的信息. 如果你没有COMMIT事务,ORACLE会将数据恢复到删除之前的状态(准确地说是恢复到执行删除命令之前的状况) 而当运用TRUNCATE时, 回滚段不再存放任何可被恢复的信息.当命令运行后,数据不能被恢复.因此很少的资源被调用,执行时间也会很短. (译者按: TRUNCATE只在删除全表适用,TRUNCATE是DDL不是DML)
(10) 尽量多使用COMMIT:
只要有可能,在程序中尽量多使用COMMIT, 这样程序的性能得到提高,需求也会因为COMMIT所释放的资源而减少:
COMMIT所释放的资源:
a. 回滚段上用于恢复数据的信息.
b. 被程序语句获得的锁
c. redo log buffer 中的空间
d. ORACLE为管理上述3种资源中的内部花费
INSERT INTO sm_users
(user_id, user_name, created_by, creation_date)
VALUES (1, 'Tang', -1, SYSDATE);
建议用如下方式操作:
DECLARE
v_user_id sm_users.user_id%TYPE;
v_user_name sm_users_user_name%TYPE;
v_created_by sm_users.created_by%TYPE;
v_creation_date sm_users.creation_date%TYPE;
BEGIN
INSERT INTO sm_users
(user_id, user_name, created_by, creation_date)
VALUES (v_user_id, v_user_name, v_created_by, v_creation_date);
1.3 Operator 的使用规范
比较容易写及清晰易懂
但效能是比较低的
ORACLE试图将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查询外层的表记录,如果转换成功则直接采用多个表的连接方式查询。由此可见用IN的
SQL
至少多了一个转换的过程。一般的
SQL
都可以转换成功,但对于
含有
分组统计等方面的
SQL
就不能转换了。
NOT IN
此操作是强列推荐不使用的,因为不能应用表的索引。
推荐方案:用NOT EXISTS 或(Outer-Join+判断为空)方案代替
SELECT deptno
FROM dept
WHERE deptno NOT IN(SELECT deptno
FROM emp)
建议写成:
SELECT deptno
FROM dept, emp
WHERE dept.deptno = emp.deptno(+) AND emp.deptno IS
NULL
永远不会用到索引的
推荐方案:用其它相同功能的操作运算代替,如:
a<>0 改为 a>0 or a<0
a<>’’ 改为 a>’’
IS
NULL
或IS NOT
NULL
一般是不会应用索引的,因为B-tree索引是不索引空
值
的。
推荐方案:用其它相同功能的操作运算代替,如:
a is not
null
改为 a>0 或a>’’
不允许字段为空,而用一个default代替空
值
,如业扩申请中状态区位不允许为空, default为申请。
有索引就会采用索引查找
但有的情况下可以对它进行优化
如一个表有100万记录,一个数
值
型字段A,30万记录的A=0,30万记录的A=1,39万记录的A=2,1万记录的A=3。那么执行A>2与A>=3的效果就有很大的区别了,因为A>2时ORACLE会先找出为2的记录索引再进行比较,而A>=3时ORACLE则直接找到=3的记录索引。
LIKE
LIKE可以应用通配符查询,里面的通配符组合可能达到几乎是任意的查询,但是如果用得不好则会产生性能上的问题,如LIKE ‘%5400%’ 这种查询不会引用索引,而LIKE ‘X5400%’则会引用范围索引。性能肯定大大提高。
UNION
SQL
在运行时先取出数个查询的结果,再用
排序
空间进行
排序
删除重复的记录,最后返回结果集,如果表数据量大的话可能会导致用磁盘进行
排序
。
实际大部分应用中是不会产生重复的记录,推荐采用UNION ALL操作符替代UNION,因为UNION ALL操作只是简单的将两个结果合并后就返回。
Exists
示例:当有 A、B 两个结果集,当结果集 B 很大时,A 较小时,适用 exists,如:
SELECT *
FROM a
WHERE EXISTS(SELECT 1
FROM b
WHERE a.COLUMN = b.COLUMN);
当结果集 A 很大时,B 很小时,适用 in,如:
SELECT *
FROM a
WHERE a.COLUMN IN(SELECT b.COLUMN
FROM b)
1.4
SQL
书写的影响
同一功能同一性能不同写法
SQL
的影响
Select * from zl_yhjbqk
Select * from dlyx.zl_yhjbqk(带表所有者的前缀)
Select * from DLYX.ZL_YHJBQK(大写表名)
Select * from DLYX.ZL_YHJBQK(中间多了空格)
以上四个
SQL
在ORACLE分析整理之后产生的结果及执行的时间是一样的,但是从ORACLE共享内存SGA的原理,可以得出ORACLE对每个
SQL
都会对其进行一次分析,并且占用共享内存,如果将
SQL
的字符串及格式写得完全相同则ORACLE只会分析一次,共享内存也只会留下一次的分析结果,这不仅可以减少分析
SQL
的时间,而且可以减少共享内存重复的信息,ORACLE也可以准确统计
SQL
的执行频率。
WHERE后面的条件顺序影响
Select * from zl_yhjbqk where dy_dj = '1KV以下' and xh_bz=1
Select * from zl_yhjbqk where xh_bz=1 and dy_dj = '1KV以下'
以上两个
SQL
中dy_dj(电压等级)及xh_bz(销户标志)两个字段都没进行索引,所以执行的时候都是全表扫描,第一条
SQL
的dy_dj = '1KV以下'条件在记录集内比率为99%,而xh_bz=1的比率只为0.5%,在进行第一条
SQL
的时候99%条记录都进行dy_dj及xh_bz的比较,而在进行第二条
SQL
的时候0.5%条记录都进行dy_dj及xh_bz的比较,以此可以得出第二条
SQL
的CPU占用率明显比第一条低。
查询表顺序的影响
在FROM后面的表中的列表顺序会对
SQL
执行性能影响,在没有索引及ORACLE没有对表进行统计分析的情况下ORACLE会按表出现的顺序进行链接,由此因为表的顺序不对会产生十分耗服务器资源的数据交叉。(注:如果对表进行了统计分析,ORACLE会自动先进小表的链接,再进行大表的链接)
对条件字段的一些优化
采用函数处理的字段不能利用索引,如:
substr(hbs_bh,1,4)=’5400’,优化处理:hbs_bh like ‘5400%’
trunc(sk_rq)=trunc(sysdate), 优化处理: sk_rq>=trunc(sysdate) and sk_rq<trunc(sysdate+1)
进行了显式或隐式的运算的字段不能进行索引,如:
ss_df+20>50,优化处理:ss_df>30
‘X’||hbs_bh>’X5400021452’,优化处理:hbs_bh>’5400021542’
sk_rq+5=sysdate,优化处理:sk_rq=sysdate-5
hbs_bh=5401002554,优化处理:hbs_bh=’ 5401002554’
注:此条件对hbs_bh 进行隐式的to_number转换,因为hbs_bh字段是字符型
条件内包括了多个本表的字段运算时不能进行索引,如:
ys_df>cx_df,无法进行优化
qc_bh||kh_bh=’5400250000’,优化处理:qc_bh=’5400’ and kh_bh=’250000’
HINT
是在ORACLE产生的
SQL
分析执行路径不满意的情况下要用到的。它可以对
SQL
进行以下方面的提示
目标方面的提示:
COST(按成本优化)
RULE(按规则优化)
CHOOSE(缺省)(ORACLE自动选择成本或规则进行优化)
ALL_ROWS(所有的行尽快返回)
FIRST_ROWS(第一行资料尽快返回)
执行方法的提示:
USE_NL(使用NESTED LOOPS方式联合)
USE_MERGE(使用MERGE JOIN方式联合)
USE_HASH(使用HASH JOIN方式联合)
索引提示:
INDEX(TABLE INDEX)(使用提示的表索引进行查询)
其它高级提示(如并行处理等等)
1.5 索引的规则:
建立索引常用的原则如下:
1. 表的主键、外键必须有索引
2. 数据量超过 1000 行的表应该有索引
3. 经常与其它表进行连接的表,在边接字段上应建立索引
4. 经常出现在 where 子句中的字段且过滤性极强的,特别是大表的字段,应该建立索引
5. 索引字段,尽量避免
值
为
null
6. 复合索引的建立需要仔细分析;尽量考虑用单字段索引代替:
正确选择复合索引中的第一个字段,一般是选择性较好的且在 where 子句中常的字段上。
复合索引的几个字段是否经常同时以and方式出现在where子句中?单字段查询是否极少甚至没有?如果是,则可以建立复合索引;否则考虑单字段索引。
如果复合索引中包含的字段经常单独出现在 where 子句中,则分解为多个单字段索引。
如果复合索引所包含的字段超过 3 个,那么仔细考虑其必要性,考虑减少复合的字段。
如果既有单字段索引,又有这几个字段上的复合索引,一般可以删除复合索引;
7. 频繁 DDL 的表,不要建立太多的索引
8. 删除无用的索引,避免对执行计划造成负面影响
9. 让
SQL
语句用上合理的索引,合理让
SQL
语句使用索引的原则如下:
首先,看是否用上了索引,对于该使用索引而没有用上索引的
SQL
语句,应该想办法用上索引。
其次,看是否用上正确的索引了,特别复杂的
SQL
语句,当其中 where 子句包含多个带有索引的字段时,更应该注意索引的选择是否合理。错误的索引不仅不会带来性能的提高,相反往往导致性能的降低。
针对如何用上合理的索引,以 Oracle 数据中的例子进行说明:
任何对列的操作都可能导致全表扫描,这里所谓的操作包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等式的右边,甚至去掉函数。
避免不必要的类型转换,要了解“隐藏”的类型转换。
增加查询的范围,限制全范围的搜索。
索引选择性低,但资料分布差异很大时,仍然可以利用索引提高效率。
Oracle 优化器无法用上合理索引的情况下,利用 hint 强制指定索引。
使用复合索引且第一个索引字段没有出现在 where 中时,建议使用 hint 强制。
1.6 索引使用优化
建立Plan_Table
CREATE TABLE PLAN_TABLE
STATEMENT_ID VARCHAR2(30),
TIMESTAMP DATE,
REMARKS VARCHAR2(80),
OPERATION VARCHAR2(30),
OPTIONS VARCHAR2(30),
OBJECT_NODE VARCHAR2(128),
OBJECT_OWNER VARCHAR2(30),
OBJECT_NAME VARCHAR2(30),
OBJECT_INSTANCE NUMBER(38),
OBJECT_TYPE VARCHAR2(30),
OPTIMIZER VARCHAR2(255),
SEARCH_COLUMNS NUMBER(38),
ID NUMBER(38),
PARENT_ID NUMBER(38),
POSITION NUMBER(38),
OTHER LONG
Syntax
explain plan set statement_id = user_define for select ...
将结果显示
SELECT LPAD(' ', 2 *(LEVEL - 1)) || operation op, options, object_name,
POSITION
FROM plan_table
START WITH ID = 0 AND STATEMENT_ID = user_define
CONNECT BY PRIOR ID = parent_id AND STATEMENT_ID = user_define
如要测试下面
SQL
:
SELECT c.short, a.cday, a.card_no, a.qty
FROM sales.stockiohis a, sales.product_info b, sales.vendor c
WHERE a.card_no = b.card_no
AND b.vendorid = c.vendorid
AND a.produce_no = '2007090001'
AND a.CATEGORY = '10'
AND a.iotype = '1'
新增文件:例 d:\mydoc\plan.
sql
'0001'为user_define为使用者自定义编号
EXPLAIN PLAN SET STATEMENT_ID = '0001' FOR
SELECT 'X'
FROM sales.stockiohis a ,sales.product_info b ,sales.vendor c
WHERE a.card_no = b.card_no AND b.vendorid = c.vendorid
AND a.produce_no = '2007090001' AND a.CATEGORY = '10' AND a.iotype = '1'
SET arraysize 1
SET line 100
COLUMN op format a40
COLUMN object_name format a20
COLUMN options format a20
SELECT LPAD(' ', 2 *(LEVEL - 1)) || operation op, options, object_name,
POSITION
FROM plan_table
START WITH ID = 0 AND STATEMENT_ID = '0001'
CONNECT BY PRIOR ID = parent_id AND STATEMENT_ID = '0001'
DELETE FROM plan_table
WHERE STATEMENT_ID = '0001'
COMMIT
1.7 避免不必要的
排序
说明:对查询结果进行
排序
会大大的降低系统的性能,group与union都会对数据作
排序
,要耗费较多的内存,视状况用union all既可,不然有时数据太大又要进行union的
排序
,会导致Oracle数据库SORT_AREA_SIZE不足发生系统错误。
1.8 对于数字型的Primary Key,建议用序列 sequence 产生。
说明:除非是单据的单号,要求必须是唯一,并且依据流水号不可以跳号,不然在大量交易的表格中,不在乎跳耗时,要取得唯一的Primary Key 建议使用Oracle Sequence这样速度会较快,而且不会有锁定(Lock)的问题。
p
sql
-h localhost -U postgres
CREATE DATABASE cbx6_qa_0831 WITH OWNER postgres ENCODING=’UTF8’;
pg_restore -h localhost -U postgres -W -O -d cbx6_qa_0831 D:\db\cbx_qa_2-20180515.DUMP
在
排序
时,我们可能会遇到
排序
字段为
null
的情况,但是又需要该
null
数据(即不能限制该字段is not
null
),而一般情况下我们都希望非
null
数据在前面。我们来看下这两种情况:
升序
排序
(默认
排序
)时,
null
默认会放在最后面,当然如果我们需要
null
在前面,可以这样:ORDER BY tn_time ASC
NULL
S FIRST
降序时,
null
默认会放在最前面,我们可以使用 ORDER BY tn_time DESC
NULL
S LAST 将
null
放到最后面。
参考:https://b
环境:postgre
sql
9.5在order by 语句后添加
null
s first例:select product_id,product_name,sale_price,regist_date,
sum (sale_price) over (order by regist_date
null
s first) as sum_sale_price
from product结果:...
在my
sql
中认为
null
在
排序
时为最小
值
,即ASC
排序
时在最前面,DESC
排序
时在最后
oracle中认为
null
在
排序
时为最大
值
,即ASC
排序
时在最后面,DESC
排序
时在最前
order by在进行多个字段
排序
时,如 select * from 表名 where 条件 order by id ASC,age DESC
先是按 id 升序排列 (优先)
如果 id 字段 有些是
sql
server 认为
null
最小。
升序排列:
null
值
默认排在最前。
要想排后面,则:order by case when col is
null
then 1 else 0 end ,col
降序排列:
null
值
默认排在最后。
要想排在前面,则:order by case when col is
null
then 0 else 1...
【Python】检测字符串的方法
m0_69017437:
【Yarn】工作机制及任务提交流程
菜菜的大数据开发之路:
【SQL】update中使用case when
heao1440458992:
【Python】Pycharm中plot绘图不能显示
罗斯没有石头墙: