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