设为首页 加入收藏

TOP

要养成良好的书写Sql的习惯(二)
2014-11-24 03:04:57 来源: 作者: 【 】 浏览:11
Tags:养成 良好 书写 Sql 习惯
的表的字段,这种子查询就叫作相关子查询。

  相关子查询可以用IN、NOT IN、EXISTS、NOT EXISTS引入。 关于相关子查询,应该注意:

  (1) NOT IN、NOT EXISTS的相关子查询可以改用LEFT JOIN代替写法。比如:

SELECT PUB_NAME FROM PUBLISHERS WHERE PUB_ID NOTIN (SELECT PUB_ID FROM TITLES WHERE TYPE ='BUSINESS')

  可以改写成:

SELECT A.PUB_NAME FROM PUBLISHERS A LEFTJOIN TITLES B ON B.TYPE ='BUSINESS'AND A.PUB_ID=B. PUB_ID WHERE B.PUB_ID IS NULL

  比如NOT EXISTS:

SELECT TITLE FROM TITLES

WHERE NOT EXISTS

(SELECT TITLE_ID FROM SALES WHERE TITLE_ID = TITLES.TITLE_ID)

1

可以改写成:

SELECT TITLE

FROM TITLES LEFTJOIN SALES

ON SALES.TITLE_ID = TITLES.TITLE_ID

WHERE SALES.TITLE_ID ISNULL

  2)如果保证子查询没有重复 ,IN、EXISTS的相关子查询可以用INNER JOIN 代替。比如:

SELECT PUB_NAME

FROM PUBLISHERS

WHERE PUB_ID IN

(SELECT PUB_ID

FROM TITLES

WHERE TYPE ='BUSINESS')

1

可以改写成:

SELECT A.PUB_NAME --SELECT DISTINCT A.PUB_NAME

FROM PUBLISHERS A INNERJOIN TITLES B

ON B.TYPE ='BUSINESS'AND

A.PUB_ID=B. PUB_ID

  (3) IN的相关子查询用EXISTS代替,比如:

SELECT PUB_NAME FROM PUBLISHERS

WHERE PUB_ID IN

(SELECT PUB_ID FROM TITLES WHERE TYPE ='BUSINESS')

  可以用下面语句代替:

SELECT PUB_NAME FROM PUBLISHERS WHERE EXISTS

(SELECT1FROM TITLES WHERE TYPE ='BUSINESS'AND

PUB_ID= PUBLISHERS.PUB_ID)

  4) 不要用COUNT(*)的子查询判断是否存在记录,最好用LEFT JOIN或者EXISTS,比如有人写这样的语句:

SELECT JOB_DESC FROM JOBS

WHERE (SELECTCOUNT(*) FROM EMPLOYEE WHERE JOB_ID=JOBS.JOB_ID)=0

  应该改成:

SELECT JOBS.JOB_DESC FROM JOBS LEFTJOIN EMPLOYEE

ON EMPLOYEE.JOB_ID=JOBS.JOB_ID

WHERE EMPLOYEE.EMP_ID ISNULL

  

SELECT JOB_DESC FROM JOBS

WHERE (SELECT COUNT(*) FROM EMPLOYEE WHERE JOB_ID=JOBS.JOB_ID)0

  应该改成:

SELECT JOB_DESC FROM JOBS

WHEREEXISTS (SELECT 1 FROM EMPLOYEE WHERE JOB_ID=JOBS.JOB_ID)

  七:尽量使用索引

  建立索引后,并不是每个查询都会使用索引,在使用索引的情况下,索引的使用效率也会有很大的差别。只要我们在查询语句中没有强制指定索引,索引的选择和使用方法是SQLSERVER的优化器自动作的选择,而它选择的根据是查询语句的条件以及相关表的统计信息,这就要求我们在写SQL语句的时候尽量使得优化器可以使用索引。为了使得优化器能高效使用索引,写语句的时候应该注意:

  (1)不要对索引字段进行运算,而要想办法做变换,比如:

SELECT ID FROM T WHERE NUM/2=100

应改为:

SELECT ID FROM T WHERE NUM=100*2

SELECT ID FROM T WHERE NUM/2=NUM1

如果NUM有索引应改为:

SELECT ID FROM T WHERE NUM=NUM1*2

如果NUM1有索引则不应该改。

  (2)发现过这样的语句:

SELECT 年,月,金额FROM 结余表WHERE100*年+月=2010*100+10

1

应该改为:

SELECT 年,月,金额FROM 结余表WHERE 年=2010 AND 月=10

  (3)不要对索引字段进行格式转换

日期字段的例子:

WHERECONVERT(VARCHAR(10), 日期字段,120)='2010-07-15'

应该改为

WHERE日期字段 ='2010-07-15'AND 日期字段'2010-07-16'

ISNULL转换的例子:

WHEREISNULL(字段,'')''应改为:WHERE字段''

WHEREISNULL(字段,'')=''不应修改

WHEREISNULL(字段,'F') ='T'应改为: WHERE字段='T'

WHEREISNULL(字段,'F')'T'不应修改

  (4) 不要对索引字段进行格式转换

WHERELEFT(NAME, 3)='ABC' 或者WHERE SUBSTRING(NAME,1, 3)='ABC'

应改为: WHERE NAME LIKE'ABC%'

日期查询的例子:

WHEREDATEDIFF(DAY, 日期,'2010-06-30')=0

应改为:WHERE 日期='2010-06-30' AND 日期'2010-07-01'

WHEREDATEDIFF(DAY, 日期,'2010-06-30')0

应改为:WHERE 日期'2010-06-30'

WHEREDATEDIFF(DAY, 日期,'2010-06-30')=0

应改为:WHERE 日期'2010-07-01'

WHEREDATEDIFF(DAY, 日期,'2010-06-30')0

应改为:WHERE 日期='2010-07-01'

WHEREDATEDIFF(DAY, 日期,'2010-06-30')=0

应改为:WHERE 日期='2010-06-30'

  (5)不要对索引字段使用函数

WHERE LEFT(NAME, 3)='ABC' 或者WHERE SUBSTRING(NAME,1, 3)='ABC'

应改为: WHERE NAME LIKE 'ABC%'

日期查询的例子:

WHEREDATEDIFF(DAY, 日期,'2010-06-30')=0

应改为:WHERE 日期='2010-06-30'AND 日期'2010-07-01'

WHEREDATEDIFF(DAY, 日期,'2010-06-30')0

应改为:WHERE 日期'2010-06-30'

WHEREDATEDIFF(DAY, 日期,'2010-06-30')=0

应改为:WHERE 日期'2010-07-01'

WHEREDATEDIFF(DAY, 日期,'2010-06-30')0

应改为:WHERE 日期='2010-07-01'

WHEREDATEDIFF(DAY, 日期,'201

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇MongoDB、HandlerSocket和MySQL性.. 下一篇解决:在建立与服务器的连接时出..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·C语言中如何将结构体 (2025-12-24 22:20:09)
·纯C语言结构体成员变 (2025-12-24 22:20:06)
·C语言中,指针函数和 (2025-12-24 22:20:03)
·哈希表 - 菜鸟教程 (2025-12-24 20:18:55)
·MySQL存储引擎InnoDB (2025-12-24 20:18:53)