SQL Learn
Table of Contents
1 检索数据
1.1 检索单个列
SELECT prod_name FROM Products;
prod_name |
---|
Fish bean bag toy |
Bird bean bag toy |
Rabbit bean bag toy |
8 inch teddy bear |
12 inch teddy bear |
18 inch teddy bear |
Raggedy Ann |
King doll |
Queen doll |
1.2 检索多个列
SELECT prod_id, prod_name, prod_price FROM Products;
"Put Disqus into Org mode website postamble. Do not show disqus for the Archive and the Index." (concat (cond ((string= (car (plist-get info :title)) "Archive") "") ((string= (car (plist-get info :title)) "Index") "") ((string= (car (plist-get info :title)) "GitHub -> IO ()") "") (t "<div id='disqus_thread'></div> <script type='text/javascript'> // required: replace example with your forum shortname var disqus_shortname = 'YOUR DISQUS NAME HERE'; (function() { var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true; dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js'; (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq); })(); </script> <noscript><p>Please enable JavaScript to view the <a href='http://disqus.com/?ref_noscript'>comments powered by Disqus.</a></p> </noscript>")) (format "<div class='footer'> Copyright 2014 AUTHOR<br/> Last updated %s <br/> Built with %s <br/> %s HTML </div> <script type='text/javascript'> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'PUT YOUR TRACKING ID HERE', 'auto'); ga('send', 'pageview');
</script>" (format-time-string "%Y-%m-%d") org-html-creator-string org-html-validation-link))).99 |
RYL01 | King doll | 9.49 |
RYL02 | Queen doll | 9.49 |
1.3 检索所有列
SELECT * FROM Products;
1.4 检索不同的值
DINSTINCT 关键字作用于所有的列
SELECT DISTINCT vend_id FROM Products;
1.5 限制结果
显示指定行数据
SELECT prod_name FROM Products LIMIT 5; SELECT prod_name FROM Products LIMIT 5 OFFSET 5;
prod_name |
18 inch teddy bear |
Raggedy Ann |
King doll |
Queen doll |
LIMIT 5 指示 MySQL 返回不超过5行的数据; LIMIT 5 OFFSET 5 指示 MySQL 从第5行起的5行数据;
1.6 使用注释
行内注释
SELECT prod_name -- 这是一条注释 FROM Products;
整行注释
# 这是一条注释 SELECT prod_name FORM Products;
多行注释
/* 这是多行 注释*/ SELECT prod_name FROM Products;
2 排序检索数据
2.1 排序数据
ORDER BY 子句取一个或多个列的名字,据此对输出进行排序:
SELECT prod_name FROM Products ORDER BY prod_name;
对 prod_name 列以字母顺序排序数据注意:在指定 ORDER BY 子句时,应该保证它是 SELECT 语句中最后一条子句,如果它不是最后的子句,将会出现错误信息。通常,ORDER BY 子句中使用的列僵尸为显示而选择的列。但是,实际上并不一定要这样,用非检索的列排序数据是完全合法的。
2.2 按多个列排序
要按多个列排序,简单指定列名,列名之间用逗号分开即可。
SELECT prod_id, prod_price, prod_name FROM Products ORDER BY prod_price, prod_name;
2.3 按列位置排序
ORDER BY 还支持按相对列位置进行排序。
SELECT prod_id, prod_price, prod_name FROM Products ORDER BY 2, 3;
这里用列的相对位置编号取代列名进行排序。
2.4 指定排序方向
默认排序是升序。
SELECT prod_id, prod_price, prod_name FROM Products ORDER BY prod_price DESC; SELECT prod_id, prod_price, prod_name FROM Products ORDER BY prod_price DESC, prod_name;
prod_id | prod_price | prod_name |
BR03 | 11.99 | 18 inch teddy bear |
RYL01 | 9.49 | King doll |
RYL02 | 9.49 | Queen doll |
BR02 | 8.99 | 12 inch teddy bear |
BR01 | 5.99 | 8 inch teddy bear |
RGAN01 | 4.99 | Raggedy Ann |
BNBG02 | 3.49 | Bird bean bag toy |
BNBG01 | 3.49 | Fish bean bag toy |
BNBG03 | 3.49 | Rabbit bean bag toy |
3 过滤数据
3.1 使用 where 子句
在 SELECT 语句中,数据根据 WHERE 子句中指定的搜索条件进行过滤。
SELECT prod_name, prod_price FROM Products WHERE prod_price = 3.49;
Tips: 在同时使用 ORDER BY 和 WHERE 子句时,应该让 ORDER BY 位于 WHERE 之后。
3.2 WHERE 子句操作符
操作符 | 说明 |
---|---|
= | 等于 |
<> | 不等于 |
!= | 不等于 |
< | 小于 |
<= | 小于等于 |
!< | 不小于 |
> | 大于 |
>= | 大于等于 |
!> | 不大于 |
BETWEEN | 在指定的两个值之间 |
IS NULL | 为 NULL 值 |
- 检查单个值
SELECT prod_name, prod_price FROM Products WHERE prod_price < 10;
- 不匹配查询
SELECT vend_id, prod_name FROM Products WHERE vend_id <> 'DLL01';
- 范围值检查
使用 BETWEEN 操作符检查某个范围值
SELECT prod_name, prod_price FROM Products WHERE prod_price BETWEEN 5 AND 10;
- 空值检查
NULL 无值(no value),它与字段包含0、空字符串或仅仅包含空格不同。
SELECT cust_name FROM Customers WHERE cust_email IS NULL;
4 高级数据过滤
4.1 组合 WHERE 子句
多个 WHERE 子句进行数据过滤;有 AND 子句或 OR 子句
- AND 操作符
SELECT prod_id, prod_price, prod_name FROM Products WHERE vend_id = 'DLL01' AND prod_price <=4;
- OR 操作符
SELECT prod_name, prod_price FROM Products WHERE vend_id = 'DLL01' OR vend_id = 'BRS01';
- 求值顺序
SQL 在处理 OR 操作符,优先处理 AND 操作符。
SELECT prod_name, prod_price FROM Products WHERE vend_id = 'DLL01' OR vend_id = 'BRS01' AND prod_price >= 10; SELECT prod_name, prod_price FROM Products WHERE (vend_id = 'DLL01' OR vend_id = 'BRS01') AND prod_price >= 10;
prod_name prod_price 18 inch teddy bear 11.99 Tips: 任何时候使用具有 AND 和 OR 操作符的 WHERE 子句,都应该使用圆括号明确地分组操作符。
- IN 操作符
IN 操作符用来指定条件范围
SELECT prod_name, prod_price FROM Products WHERE vend_id IN ('DLL01', 'BRS01') ORDER BY prod_name;
Tips: 使用 IN 操作符的有点:
- 在有很多合法的选项时,IN 操作符的语法更清楚,更直观;
- 在与其他 AND 和 OR 操作符组合使用 IN 时,求值顺序更容易管理;
- IN 操作符一般比一组 OR 操作符执行的更快;
- IN 的最大有点是包含其他 SELECT 语句,能够更动态地建立 WHERE 子句;
- NOT 操作符
WHERE 子句中的 NOT 操作符有且只有一个功能,那就是否定其后所跟的任何条件。
SELECT prod_name FROM Products WHERE NOT vend_id = 'DLL01' ORDER BY prod_name;
5 用通配符进行过滤
5.1 LIKE 操作符
通配符(wildcard) 用来匹配值的一部分的特殊字符。 搜索模式(search pattern) 由字面值、通配符或两者组合构成的搜索条件。
- 百分号(%)通配符
最常使用的通配符是百分号(%)。在搜索串中,%表示任何字符出现任意次数。
SELECT prod_id, prod_name FROM Products WHERE prod_name LIKE 'Fish%'; # 通配符可在搜索模式中的任意位置使用 SELECT prod_id, prod_name FROM Products WHERE prod_name LIKE '%bean bag%';
prod_id prod_name BNBG01 Fish bean bag toy BNBG02 Bird bean bag toy BNBG03 Rabbit bean bag toy Tips: %代表搜索模式中给定位置的0个、1个或多个字符。但不会匹配 NULL
- 下划线(_)通配符
下划线只匹配单个字符。
SELECT prod_id, prod_name FROM Products WHERE prod_name LIKE '__ inch teddy bear';
- 方括号([])通配符
方括号()通配符用来指定一个字符集,它必须匹配指定位置(通配符的位置)的一个字符。
SELECT cust_contact FROM Customers WHERE cust_contact LIKE '[JM]%' ORDER BY cust_contact;
5.2 使用通配符的技巧
- 不要过度使用通配符。如果其他操作符能够达到相同的目的,应该使用其他操作符。
- 在确定需要使用通配符时,也尽量不要把它们用在搜索模式的开始处。把通配符置于开始处,搜索起来是最慢的。
- 仔细注意通配符的位置。如果放错了地方,可能不会返回想要的数据
6 创建计算字段
6.1 计算字段
需要特别注意,只有数据库知道 SELECT 语句中哪些列是实际的表列,哪些列是计算字段在 SQL 语句内可完成的许多转换和格式化工作都可以直接在客户端应用程序内完成。但一般来说,在数据库服务器上完成这些操作比在客户端中完成要快得多。
6.2 拼接字段
拼接(concatenate) 将值联结到一起构成单个值。 注意 Access 和 SQL Server 使用+号。DB@、Oracle、PostgreSQL、SQLite 和 Open Office Base 使用||。MySQL 和 MariaDB 使用 concat。
SELECT CONCAT(vend_name, '(', vend_country, ')') FROM Vendors ORDER BY vend_name;
大多数 DBMS 都支持 RTRIM()(去掉字符串右边的空格)、LTRIM()(去掉字符串左边的空格)、以及 TRIM()(去掉字符串左右两边的空格)。 使用别名 别名(alias)是一个字段或值的替换名。别名用 AS 关键字赋予。
SELECT CONCAT(vend_name, '(', vend_country, ')') as vend_title FROM Vendors ORDER BY vend_name;
Tips: 在很多 DBMS 中,AS 关键字是可选的,不过最好使用它,这被视为一条最佳实践。
6.3 执行算数计算
计算字段的另一个常见用途是对检索出的数据进行算术计算。
SELECT prod_id, quantity, item_price, quantity*item_price AS expanded_price FROM OrderItems WHERE order_num = 20008;
7 使用数据处理函数
7.1 函数
DBMS 函数的差异
函数 | Access | DB2 | Oracle | PostgreSQL | SQLite | MySQL/MariaDB | SQL Server |
---|---|---|---|---|---|---|---|
提取字符串的组成部分 | MID() | SUBSTR() | SUBSTR() | SUBSTR() | SUBSTR() | SUBSTRING() | SUBSTRING() |
数据类型转换 | 多个函数 | CAST() | 多个函数 | CAST() | CONVERT() | CONVERT() | |
取当前日期 | NOW() | CURRENT_DATE() | SYSDATE() | CURRENT_DATE() | DATE() | CURDATE() | GETDATE() |
8 汇总数据
8.1 聚集函数
聚集数据