SQL Server零碎知识点总结

933 阅读6分钟

1、规范

对SQL关键字 使用大写,而对列名和表名使用小写,

SELECT prod_name 
FROM Products; 

2、通配符

1、通配符也可以出现在搜索模式的中间,虽然这样做不太有用。下面的例 子找出以F起头、以y结尾的所有产品:

输入▼ 
SELECT prod_name 
FROM Products 
WHERE prod_name LIKE 'F%y';

说明:请注意后面所跟的空格 包括Access在内的许多DBMS都用空格来填补字段的内容。例如,如 果某列有50个字符,而存储的文本为Fish bean bag toy(17个字 符),则为填满该列需要在文本后附加33个空格。这样做一般对数据 及其使用没有影响,但是可能对上述SQL语句有负面影响。子句 WHERE prod_name LIKE 'F%y'只匹配以F开头、以y结尾的 prod_name。如果值后面跟空格,则不是以y结尾,所以Fish bean bag toy就不会检索出来。简单的解决办法是给搜索模式再增加一 个%号:'F%y%'还匹配y之后的字符(或空格)。更好的解决办法是 用函数去掉空格。请参阅第8课。

警告:请注意NULL 通配符%看起来像是可以匹配任何东西,但有个例外,这就是NULL。 子句WHERE prod_name LIKE '%'不会匹配产品名称为NULL的行

2、需要特别注意,除了能匹配一个或多个字符外,%还能匹配0个字符。% 代表搜索模式中给定位置的0个、1个或多个字符

3、下划线_的用途与%一样,但它只匹 配单个字符,而不是多个字符

4、 方括号([ ])通配符 找出所有名字以J或M起头的联系人,可进行如下查询:

输入▼ 
SELECT cust_contact 
FROM Customers 
WHERE cust_contact LIKE '[JM]%' 
ORDER BY cust_contact; 

[JM]匹配任何以方括号中字母开头的联系人名,它也只能 匹配单个字符。因此,任何多于一个字符的名字都不匹配。[JM]之后 的%通配符匹配第一个字符之后的任意数目的字符,返回所需结果。 此通配符可以用前缀字符^(脱字号)来否定。例如,下面的查询匹配 不以J或M起头的任意联系人名(与前一个例子相反):

输入▼ 
SELECT cust_contact 
FROM Customers 
WHERE cust_contact LIKE '[^JM]%' 
ORDER BY cust_contact; 

正如所见,SQL的通配符很有用。但这种功能是有代价的,即通配符搜 索一般比前面讨论的其他搜索要耗费更长的处理时间。这里给出一些使 用通配符时要记住的技巧。 不要过度使用通配符。如果其他操作符能达到相同的目的,应该使 用其他操作符。 在确实需要使用通配符时,也尽量不要把它们用在搜索模式的开始 处。把通配符置于开始处,搜索起来是最慢的。 仔细注意通配符的位置。如果放错地方,可能不会返回想要的数 据

3、拼接字段

输入▼ 
SELECT vend_name + ' (' + vend_country + ')' 
FROM Vendors 
ORDER BY vend_name; 

输出▼ 
----------------------------------------------------------- 
Bear Emporium (USA ) 
Bears R Us (USA )
输入▼ 
SELECT RTRIM(vend_name) + ' (' + RTRIM(vend_country) + ')'FROM Vendors 
ORDER BY vend_name; 
输出▼ 
----------------------------------------------------------- 
Bear Emporium (USA) 
Bears R Us (USA) 
Doll House Inc. (USA) 
Fun and Games (England) 
Furball Inc. (USA) 
Jouets et ours (France) 

分析▼ RTRIM()函数去掉值右边的所有空格。通过使用RTRIM(),各个列都进 行了整理。 说明:TRIM函数 大多数DBMS都支持RTRIM()(正如刚才所见,它去掉字符串右边的 空格)、LTRIM()(去掉字符串左边的空格)以及TRIM()(去掉字符 串左右两边的空格)。

4、执行算术计算

输入▼ 
SELECT prod_id, 
quantity, 
item_price, 
quantity*item_price AS expanded_price 
FROM OrderItems 
WHERE order_num = 20008; 

输出▼ 
prod_id           quantity         item_price         expanded_price 
----------       -----------      ------------      ----------------- 
RGAN01               5               4.9900             24.9500 
BR03                 5               11.9900            59.9500 
BNBG01              10               3.4900             34.9000
BNBG02              10               3.4900             34.9000 
BNBG03              10               3.4900             34.9000 

SELECT语句为测试、检验函数和计算提供了很好的方法。虽 然SELECT通常用于从表中检索数据,但是省略了FROM子句后就是简 单地访问和处理表达式,例如SELECT 3 * 2;将返回6,SELECT Trim(' abc ');将返回abc,SELECT Now();使用Now()函数返回 当前日期和时间。现在你明白了,可以根据需要使用SELECT语句进 行检验

5、函数

大多数SQL实现支持以下类型的函数。 1、用于处理文本字符串(如删除或填充值,转换值为大写或小写)的 文本函数。 2、用于在数值数据上进行算术操作(如返回绝对值,进行代数运算) 的数值函数。 3、用于处理日期和时间值并从这些值中提取特定成分(如返回两个日 期之差,检查日期有效性)的日期和时间函数。 4、返回DBMS正使用的特殊信息(如返回用户登录信息)的系统函 数

6、分组

Group by

7、过滤分组Having

WHERE不能完成任务,因为WHERE过滤指定的是行而不是分组。事实 上,WHERE没有分组的概念

说明:HAVING和WHERE的差别 这里有另一种理解方法,WHERE在数据分组前进行过滤,HAVING在数 据分组后进行过滤。这是一个重要的区别,WHERE排除的行不包括在 分组中。这可能会改变计算值,从而影响HAVING子句中基于这些值 过滤掉的分组。

提示:不要忘记ORDER BY 一般在使用GROUP BY子句时,应该也给出ORDER BY子句。这是保证 数据正确排序的唯一方法。千万不要仅依赖GROUP BY排序数据。

8、SELECT子句顺序

下面回顾一下SELECT语句中子句的顺序。表10-2以在SELECT语句中使 用时必须遵循的次序,列出迄今为止所学过的子句。 表10-2 SELECT子句及其顺序

子 句 
说 明 
是否必须使用 
SELECT 
要返回的列或表达式 是 
FROM 
从中检索数据的表 
仅在从表选择数据时使用 
WHERE 
行级过滤 
否 
GROUP BY 分组说明 
仅在按组计算聚集时使用 
HAVING 
组级过滤 
否 
ORDER BY 输出排序顺序 
否

9、使用NOT EXISTS 代替NOT IN

下面我们来看一下为什么尽量不使用Not In子句。

结果不准确问题

在SQL Server中,Null值并不是一个值,而是表示特定含义,其所表示的含义是“Unknow”,可以理解为未定义或者未知,因此任何与Null值进行比对的二元操作符结果一定为Null,包括Null值本身。而在SQL Server中,Null值的含义转换为Bool类型的结果为False。让我们来看一个简单的例子

select '有值' where 3 not in ('1','2',null)
查询结果
(无列名)

条件3不属于Not In后面列表的任意一个,该查询却不返回任何值,与预期的结果不同,那么具体原因就是Not In子句对于Null值的处理,在SQL Server中,Not In子句其实可以等价转换于

select '有值' where 3<>1 and 3<>2 and 3<>null

解决办法?

解决办法就是不使用Not In,而使用Not Exists作为替代。Exists的操作符不会返回Null,只会根据子查询中的每一行决定返回True或者False,当遇到Null值时,只会返回False,而不会由某个Null值导致整个子查询表达式为Null。

select col1  from (select 3 as col1) as b 
where  not exists (select * 
			       from ( select 1 as col2
					  union
					  select 2 
					  union
					  select null
					  )  as a 
					  where b.col1 = a.col2
				   )
查询结果
col1
3