SQL养成这些好习惯是一笔财富
点击关注上方“SQL数据库开发”,
设为“置顶或星标”,时间送达干货
一、查询的逻辑执行顺序
--如有表table1(ID,col1)和table2 (ID,col2)
Select A.ID, A.col1, B.col2
-- Select A.ID, col1, col2 –不要这么写,不利于将来程序扩展
from table1 A inner join table2 B on A.ID=B.ID Where …
B、纵向来看
(1)合理写WHERE子句,不要写没有WHERE的SQL语句。
(2) SELECT TOP N * --没有WHERE条件的用此替代
UPDATE EMPLOYEE SET FNAME='HAIWER'
WHERE EMP_ID=' VPA30890F'
UPDATE EMPLOYEE SET LNAME='YANG'
WHERE EMP_ID=' VPA30890F'
UPDATE EMPLOYEE SET FNAME='HAIWER',LNAME='YANG'
WHERE EMP_ID=' VPA30890F'
五、注意临时表和表变量的用法
SELECT PUB_NAME FROM PUBLISHERS
WHERE PUB_ID NOT IN
(SELECT PUB_ID FROM TITLES
WHERE TYPE = 'BUSINESS')
--可以改写成:
SELECT A.PUB_NAME FROM PUBLISHERS A
LEFT JOIN TITLES B ON B.TYPE = 'BUSINESS' AND A.PUB_ID=B. PUB_ID
WHERE B.PUB_ID IS NULL
(2)
SELECT TITLE FROM TITLES
WHERE NOT EXISTS
(SELECT TITLE_ID FROM SALES
WHERE TITLE_ID = TITLES.TITLE_ID)
可以改写成:
SELECT TITLE
FROM TITLES
LEFT JOIN SALES ON SALES.TITLE_ID = TITLES.TITLE_ID
WHERE SALES.TITLE_ID IS NULL
SELECT PUB_NAME FROM PUBLISHERS
WHERE PUB_ID IN
(SELECT PUB_ID FROM TITLES
WHERE TYPE = 'BUSINESS')
可以改写成:
SELECT A.PUB_NAME --SELECT DISTINCT A.PUB_NAME
FROM PUBLISHERS A
INNER JOIN TITLES B
ON B.TYPE = 'BUSINESS' AND A.PUB_ID=B. PUB_ID
(3)
C、
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
(SELECT 1 FROM TITLES
WHERE TYPE = 'BUSINESS' AND PUB_ID= PUBLISHERS.PUB_ID)
D、不要用
COUNT
(*)的子查询判断是否存在记录,好用
LEFT
JOIN
或者EXISTS,比如有人写这样的语句:
SELECT JOB_DESC FROM JOBS
WHERE (SELECT COUNT(*) FROM EMPLOYEE
WHERE JOB_ID=JOBS.JOB_ID)=0
--应该改成:
SELECT JOBS.JOB_DESC FROM JOBS
LEFT JOIN EMPLOYEE ON EMPLOYEE.JOB_ID=JOBS.JOB_ID
WHERE EMPLOYEE.EMP_ID IS NULL
SELECT JOB_DESC FROM JOBS
WHERE (SELECT COUNT(*) FROM EMPLOYEE
WHERE JOB_ID=JOBS.JOB_ID)<>0
--应该改成:
SELECT JOB_DESC FROM JOBS
WHERE EXISTS (SELECT 1 FROM EMPLOYEE WHERE JOB_ID=JOBS.JOB_ID)
七、尽量使用索引
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有索引则不应该改。
SELECT 年,月,金额 FROM 结余表 WHERE 100*年+月=2010*100+10
应该改为:
SELECT 年,月,金额 FROM 结余表 WHERE 年=2010 AND月=10
日期字段的例子:
WHERE CONVERT(VARCHAR(10), 日期字段,120)='2010-07-15'
应该改为
WHERE日期字段〉='2010-07-15' AND 日期字段<'2010-07-16'
ISNULL转换的例子:
WHERE ISNULL(字段,'')<>''应改为:WHERE字段<>''
WHERE ISNULL(字段,'')=''不应修改
WHERE ISNULL(字段,'F') ='T'应改为: WHERE字段='T'
WHERE ISNULL(字段,'F')<>'T'不应修改
WHERE LEFT(NAME, 3)='ABC' 或者 WHERE SUBSTRING(NAME,1, 3)='ABC'
应改为: WHERE NAME LIKE 'ABC%'
日期查询的例子:
WHERE DATEDIFF(DAY, 日期,'2010-06-30')=0
应改为:WHERE 日期>='2010-06-30' AND 日期 <'2010-07-01'
WHERE DATEDIFF(DAY, 日期,'2010-06-30')>0
应改为:WHERE 日期 <'2010-06-30'
WHERE DATEDIFF(DAY, 日期,'2010-06-30')>=0
应改为:WHERE 日期 <'2010-07-01'
WHERE DATEDIFF(DAY, 日期,'2010-06-30')<0
应改为:WHERE 日期>='2010-07-01'
WHERE DATEDIFF(DAY, 日期,'2010-06-30')<=0
应改为:WHERE 日期>='2010-06-30'
比如:
WHERE FAME+ '. '+LNAME='HAIWEI.YANG'
应改为:
WHERE FNAME='HAIWEI' AND LNAME='YANG'
八、多表连接的连接条件对索引的选择有着重要的意义,所以我们在写连接条件条件的时候需要特别注意。
考虑联接优先顺序:
(1)INNER JOIN
(2)LEFT JOIN (注:RIGHT JOIN 用 LEFT JOIN 替代)
(3)CROSS JOIN
--startof 查询在职人数
sql语句
--end of
BEGIN TRAN
UPDATE a SET 字段=''
ROLLBACK
BEGIN TRANSACTION
--事务回滚开始
--检查报错
IF ( @@ERROR > 0 )
BEGIN
--回滚操作
ROLLBACK TRANSACTION
RAISERROR('删除工作报告错误', 16, 3)
RETURN
END
--结束事务
COMMIT TRANSACTION
我是岳哥,后给大家分享我写的SQL两件套:《SQL基础知识第二版》和《SQL知识第二版》的PDF电子版。里面有各个语法的解释、大量的实例讲解和批注等等,非常通俗易懂,方便大家跟着一起来实操。
有需要的读者可以下载学习,在下面的公众号「数据前线」(非本号)后台回复关键字:SQL,就行
数据前线 ——End——
后台回复关键字:1024,获取一份精心整理的技术干货
后台回复关键字:进群,带你进入高手如云的交流群。
推荐阅读
SQL 进阶技巧(下) MySQL基本知识点梳理和查询优化 SQL 查询总是先执行SELECT语句吗? SQL 进阶技巧(上) 超全整理,MySQL常用函数
相关文章