SQL开发中容易忽视的一些小地方

lihui199111

lihui199111

2016-02-19 19:34

下面是个简单易学的SQL开发中容易忽视的一些小地方教程,图老师小编详细图解介绍包你轻松学会,喜欢的朋友赶紧get起来吧!

  做开发三年来(B/S),发现基于web 架构的项目技术主要分两大方面: 

  第一:C#,它是程序的基础,也可是其它开发语言,没有开发语言也就不存在应用程序.

  第二:数据库,现在是信息化世界,大多数信息都可以通过数据库存储来交换信息.常与应用程序互相交流信息.

  但在SQL开发应用时,我们往往只观注些常用的方法(insert delete select update),对些小细节方面(系统存储过程,函数的应用,优化分析)研究的并不多或者是知其一不知其二,所以本人想把在学习工作当中遇到的问题总结些,希望还没有重视这些方面的朋友会有帮助,少走些弯路.

  SQL中的null的用法及要注意的方面

   null:无效的, 无价值的, 等于零的.

  SQL中, NULL 与空格, 零, 都不相同. 是指为未定义或是不可用的.

  构成因素:造成某一列成为NULL 的因素可能是:

  (1),值不存在;

  (2), 值未知;

  (3), 列对表不可用.

  它与普通的值最大的异同是:

  相同点:

  1:统统属于值范畴.数字1是一个值,字符串'aaa'同样是一个值,同理 null也是一个值.

  2:都是合法的值,普通的数字,字符可以存在于表中字段,null也可以,而且是有意义的.

  不同点:

  先创建测试表:

  USE [myTestDB]

  GO

  /****** 对象: Table [dbo].[testNull] 脚本日期: 10/11/2008 13:45:14 ******/

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[testNull](
[ID] [int] IDENTITY(1,1) NOT NULL,
[a] [nchar](10) COLLATE Chinese_PRC_CI_AS NULL,
[b] [nchar](10) COLLATE Chinese_PRC_CI_AS NULL,
CONSTRAINT [PK_testNull] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

  插入相关测试值:

insert into testNull
values('1','')
insert into testNull
  
values('2',null)

  1:普通的值一般都可能进行运算符操作,例如:ID列为int,所以可以这样:ID=ID+1等,但如果一列的值为null,null+1=null,就是说null与任何运算符运算后都为null,这就是大家说的黑洞,会吃掉所有的东西.

  update testNull

  set b=b+1

  where b is null

  结论:查询后发现b的值没有变化,仍然为null.

  2:普通的值可以进行"="操作,例如条件中一般都会这样出现:sUserName='张三',如果sUserName的值为null,要想找出所有名字为null的记录时,不能这样用:sUserName=null,因为null不是一个具体的值,任何值与它比较时都会返回false.此时可借用is null 或者是is not null.

  示例查询:

  1:select * from testNull where a=null --返回空结果集

  2:select * from testNull where b is null --返回结果集 2 2 NULL

  结论:说明null是不能用"="来比较,可用is null来替换

  3:在用统计函数count时会不同,例如count(ID):统计记录数.当统计的记录中的包含有null值时,它会忽略null值.

  示例查询:

  1:select count(*),count(b) from testNull 它的返回值为2 1

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

  2: select count(*),count(isnull(b,'')) from testNull 它的返回值为2 2

  结论:对于列包含null 时,统计行数是可用count(*),或者是先把null值转换成对应的值再统计,例如count(isnull(b,''));

  4:对于in 的影响不同.

  示例查询: 查询testNull表中b的值包含在null中的记录.

  select * from testNull

  where b in(null) --没有任何记录

  结论:in在查询时会忽略null的记录,查询的时候可用is not null来查询.

  5:排序时顺序有不同:当使用ORDER BY时,首先呈现NULL值。如果你用DESC以降序排序,NULL值最后显示。

  1:select * from testNull

  1 1 ''

  2 2 NULL

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

  2:select * from testNull order by b

  2 2 NULL

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

  1 1 ''

  3:select * from testNull order by b desc

  1 1 ''

  2 2 NULL

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

  6:当使用GROUP BY时,所有的NULL值被认为是相等的。这时先多插入几条数据,方便查看结果.

insert into testNull
values('3',null)
values('4','4')
select * from testNull
select count(b) from testNull
group by b

  返回结果:

  0 1 1

  结论:可见在group by 的时候,null视为等同.

  7:永远不会有什么数据等于NULL。1不等于NULL,2也一样。但NULL也不等于NULL。所以我们只能比较它“是”或“不是”。

  总结:SQL中提供了如此众多的存储过程,函数供我们调用,而我们又真正的理解几个呢?只有真正了解它们,才会对开发中出现的种种问题迅速找出问题所在并解决它.

  表联接查询

  为了说明问题,我创建了两个表,分别是学生信息表(student),班级表(classInfo).相关字段说明本人以SQL创建脚本说明:

  测试环境:SQL2005

CREATE TABLE [dbo].[student](
[ID] [int] IDENTITY(1,1) NOT NULL,
[sUserName] [nchar](10) COLLATE Chinese_PRC_CI_AS NULL,--姓名
[sAddress] [varchar](200) COLLATE Chinese_PRC_CI_AS NULL,--地址
[classID] [int] NULL,--班级
[create_date] [datetime] NULL CONSTRAINT [DF_student_create_date] DEFAULT (getdate())--入班时间
) ON [PRIMARY]

  学生表记录:插入数据999999行.可以说的上是一个不大不小的表.

CREATE TABLE [dbo].[classInfo](
[classID] [int] IDENTITY(1,1) NOT NULL,--所属班级ID
[sClassName] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,--班级名称
[sInformation] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,--班级相关信息
[sDescription] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL,--班级描述
[iSchooling] [int] NULL,--学费
CONSTRAINT [PK_classInfo] PRIMARY KEY CLUSTERED
(
[classID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
  
) ON [PRIMARY]

  班级表:共插入100行,实际可能不存在这么多的班级.

  示例需求:查询学生的基本信息以及所属班级名称,我们都会第一时间想到用表关联,这里我列出相关实现方法.

  第一:将数据量较大的学生表放在前面.

  --大表在前

select top 1000 a.sUserName,b.sClassName from student a
inner join classInfo b on
  
a.classID=b.classID

  第二:将数据量较小的班级表放在前面.

  --小表在前

select top 1000 a.sUserName,b.sClassName from classInfo b
inner join student a on
  
a.classID=b.classID

  第三:用where 实现.

  --join与where

  select top 1000 a.sUserName,b.sClassName from classInfo b, student a

  where a.classID=b.classID

  归纳:以上三种方式查询的结果都完全相同,但它们在实现效率上会有不同吗?这里首先提出两个网络上的观点:

  网络观点一:一般要使得数据库查询语句性能好点遵循一下原则:在做表与表的连接查询时,大表在前,小表在后.

  执行计划效果如图一:

  网络观点一结论:从图上可以非常清楚的看出,三者在执行计划上完成一样.为此本人并不同意网络观点一.表在前与后并不影响最终的执行效率.大家有什么不同的意见望指教.

  说明:

  1:WHERE子句中使用的连接语句,在数据库语言中,被称为隐性连接。INNER JOIN称为显性连接。WHERE 和INNER JOIN产生的连接关系,没有本质区别,结果也一样。但是!隐性连接随着数据库语言的规范和发展,已经逐渐被淘汰,比较新的数据库语言基本上已经抛弃了隐性连接,全部采用显性连接了。

  2:join的分类:

  1 inner join:理解为“有效连接”,

  2left join:理解为“有左显示”,

  3 right join:理解为“有右显示”

  4 full join:理解为“全连接”

  3 .join可以分主次表 左联是以左边的表为主,右边的为辅,右联则相反

  网络观点二:inner join 与 where 在效率上是否一样?原文地址: http://topic.csdn.net/t/20050520/13/4022440.html 原文中有下面一段话:

  ---------------------------引用----------------------------------------------

展开更多 50%)
分享

猜你喜欢

SQL开发中容易忽视的一些小地方

编程语言 网络编程
SQL开发中容易忽视的一些小地方

一些容易忽视的卫生死角

生活常识 养生 健康
一些容易忽视的卫生死角

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

《正当防卫2》一些容易忽视的细节

电脑网络
《正当防卫2》一些容易忽视的细节

厨房卫生有哪些小细节容易忽视

健康饮食 饮食禁忌 饮食指南 饮食养生
厨房卫生有哪些小细节容易忽视

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

网页幻灯片设计中的一些小细节

平面设计 海报设计 广告设计 画报设计 签名设计 服装设计 名片设计 画册设计 版式设计 商标设计
网页幻灯片设计中的一些小细节

JQuery的一些小应用收集

Web开发
JQuery的一些小应用收集

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

DIV+CSS网页布局及网站设计常犯错误

DIV+CSS网页布局及网站设计常犯错误

Delphi中ScriptControl的高级应用(一)

Delphi中ScriptControl的高级应用(一)
下拉加载更多内容 ↓