SQL In 10 minutes
v5
1 了解SQL
数据库基础
数据库:数据库是以某种有组织的方式存储的数据集合。 表:一种结构化的文件,可以用来存储某种特定类型的数据。某种特定类型数据的结构化清单。 模式:关于数据库和表的布局及特性的信息。 列:表中的一个字段。所有表都有一个或多个列组成的。 数据类型:允许什么类型的数据。每个表列都有相应的数据类型,它限制该列中存储的数据。 数据类型兼容:数据类型及其名称是SQL不兼容的一个主要原因。虽然大多数基本数据类型得到了一致的支持,但许多高级的数据类型却没有。更糟糕的是,偶尔会有相同的数据类型在不同的DBMS中有不同的名称。 行:表中的一条记录。 主键(primary key):一列或几列,其值能够唯一标识表中每一行。 应该总是定义主键:虽然并不总是需要主键,但多数数据库设计者都会保证每个表中有主键,以便于以后的数据操作和管理。
- 任意两列不具有相同的主键值
- 每一行都必须具有一个主键值(主键列不允许空值NULL)
- 主键列不允许修改或更新
- 主键不能重用(如果某行从表中删除,他的主键不能赋值给以后的新行)
什么是SQL
Structured Query Language结构化查询语言 设计SQL的目的:提供一种从数据库中读写数据的简单有效的方法。 标准SQL由ANSI标准委员会管理,从而称为ANSI SQL。 推荐DBMS:
- MySQL(或派生的MariaDB)
- Microsoft SQL Server Express
2 检索数据
SELECT语句
检索单个列
SELECT prod_name
FROM Products;
多条SQL必须以分号(;)分割 SQL语句不区分大小写,许多开发人员喜欢对SQL关键字使用大写,而对列名和表名使用小写,这样做代码更易于阅读和调试。
SELECT prod_name
FROM Products;
SELECT prod_name FROM Products;
SELECT
prod_name
FROM
Products;
多数SQL开发人员认为,将SQL语句分成多行更容易阅读和调试。
检索多个列
SELECT prod_id, prod_name, prod_price
FROM Products;
检索所有列
SELECT *
FROM Products;
一般而言,除非你确实需要表中的每一列,否则最好别使用*通配符。虽然省事,但检索不需要的列通常会降低检索速度和应用程序的性能。 使用通配符最大的优点是可以检索出未知的列。
检索不同的值
SELECT DISTINCT vend_id
FROM Products;
不能部分使用DISTINCT,该关键字作用于所有列。
限制结果
只检索前5行。 SQLServer
SELECT TOP 5 prod_name
FROM Products;
Oracle:
SELECT prod_name
FROM Products
WHERE ROWNUM <=5;
MySQL
SELECT prod_name
FROM Products
LIMIT 5;
-- 6-10行
SELECT prod_name
FROM Products
LIMIT 5 OFFSET 5;
-- OFFSET从0开始
SELECT prod_name
FROM Products
LIMIT 1, 3; 从1开始3行,与上面同义。
使用注释
-- 推荐两个连字符 单行,或行内
-- --------------------
-- 多行注释
-- --------------------
# 单行
/*
多行,这两种方式有些DBMS不支持
*/
3 排序检索数据
SELECT的ORDER BY子句
排序数据
子句:由一个关键字加上所提供的数据组成。例如SELECT语句的FROM子句。
SELECT prod_name
FROM Products
ORDER BY prod_name;
ORDER BY子句应该放在SELECT语句的最后,否则会出错。 可以通过非选择列进行排序,是完全合法的。
按多个列排序
-- 先对价格排序再对名称排序
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY prod_price, prod_name;
按列位置排序
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY 2, 3; -- 相当于 ORDER BY prod_price, prod_name;
优点是不用重复输入列名,缺点是如果排序的列不在选择列中,则不能使用。
指定排序方向
SELECT prod_id, prod_price, prod_name
FROM Products
ORDER BY prod_price DESC, prod_name;
DESC是降序,ASC是升序,升序是默认不写也行。
区分大小写和排序顺序 A与a相同吗?a位于B之前还是Z之后,其答案取决于数据库的设置方式。ORDER BY做不到,需要DBA的帮助。
4 过滤数据
SELECT语句的WHERE子句指定搜索条件。
使用WHERE子句
数据库表一般包含大量的数据,很少检索表中所有行。只检索所需数据需要指定搜索条件(search condition),搜索条件也成为过滤条件(filter condition)。 WHERE子句在表名之后给出。
SELECT prod_name, prod_price
FROM Products
WHERE prod_price = 3.49;
SQL过滤和应用过滤 客户端应用过滤将会极大的影响应用的性能,此外服务器不得不通过网络发送多余的数据,导致网络带宽浪费 。
WHERE子句操作符
- 大于 小于 等于 不等于<> 大于等于 小于等于
- BETWEEN AND 范围检查
- IS NULL 空值检查
字符串需要使用单引号例如 vend_id != 'DLL01';
5 高级数据过滤
如何组合WHERE子句以建立功能更强、更高级的搜索条件。还将学习NOT和IN操作符。
组合WHERE子句
AND操作符
SELECT prod_id, prod_price, prod_name
FROM Products
WHERE vend_id = 'DLL01' AND prod_price <= 4;
OR操作符
SELECT prod_id, prod_price, prod_name
FROM Products
WHERE vend_id = 'DLL01' OR vend_id = 'BRS01';
求值顺序
优先处理AND,其次是OR操作符。有括号优先运算括号中的式子。
IN操作符
SELECT prod_price, prod_name
FROM Products
WHERE vend_id IN ('DLL01', 'BRS01');
IN操作符优点:
- 语法直观
- 与AND和OR组合使用时,求值顺序更容易管理
- IN比一组OR操作符执行更快(数量少的时候)
- IN的最大优点是可以包含其他SELECT语句,能够动态的建立WHERE子句。
阿里开发手册:IN操作能避免就避免,若避免不了,评估后使元素数量保持在1000以内。
in的效率是比较低的,但不大会和LEFT JOIN做比较,一般是和exists做比较的。 in的实质就是无数个=,中间用OR连接起来 比如IN (1,2,3)实质上就是=1 or =2 or =3,效率自然不高 为什么说SQL语句中使用IN性能不高?_sql in 效率-CSDN博客
NOT操作符
有且仅有一个功能,就是否定其后所跟的任何条件。
SELECT prod_price, prod_name
FROM Products
WHERE NOT vend_id IN ('DLL01', 'BRS01');
6 用通配符进行过滤
LIKE操作符
前面都是基于已知值进行过滤,而针对未知值,例如怎样搜索产品中包含文本bean bag的所有产品?就得使用通配符。 通配符(wildcard):用来匹配值的一部分的特殊字符。 搜索模式:由字面值、通配符或两者组合构成的搜索条件。 使用通配符必须使用LIKE操作符。 通配符搜索只能用于文本字段,非文本数据类型不能使用。
百分号通配符
%表示任何字符出现任意次数。
SELECT prod_id, prod_name
FROM Products
WHERE prod_name LIKE 'Fish%';
SELECT prod_id, prod_name
FROM Products
WHERE prod_name LIKE '%Fish%';
SELECT prod_id, prod_name
FROM Products
WHERE prod_name LIKE 'F%y';
后面所跟的空格,如果某列有50个字符,单钱存储了17个字符后面补充33个空格,检索是引用'F%y%',在MySQL中,后面不用再加%。
请注意NULL %不会匹配产品名称为NULL的行。
下划线_通配符
匹配单个字符。 DB2不支持_。
SELECT prod_id, prod_name
FROM Products
WHERE prod_name LIKE '__ inch teddy bear'; -- 匹配两个字符
方括号通配符
用来指定一个字符集,必须匹配指定位置中的一个字符。
LIKE '[JM]%'
SQL Server支持。MySQL不支持。
通配符的技巧
通配符很有用,但是这种功能是有代价的,即比前面讨论的普通搜索要耗费更长的处理时间。
- 不要过度使用通配符。如果有其他方案,应采用其他方案。
- 在确实需要使用通配符时,尽量不要放到搜索模式的开始处。
7 创建计算字段
计算字段
计算字段是运行时在SELECT语句内创建的。
字段用在计算字段场合下,列是用在数据库表中
客户端与服务器的格式:
在数据服务器上完成这些操作比在客户端中完成要快得多。
拼接字符串
可用+或两个竖杠(||)标识,在MySQL和MariaDB中,必须使用特殊的函数
SELECT CONCAT(vend_name, '(', vend_country, ')')
FROM Vendors;
Tip: 在图形化工具中,建议先写表名,在写字段名,工具会给予字段名称提示。
去空格
RTRIM去掉右边的空格,LTRIM去掉左边的空格
SELECT RTRIM(vend_name),LTRIM(vend_name)
FROM Vendors;
别名
SELECT CONCAT(vend_name, '(', vend_country, ')')
AS vend_title
FROM Vendors;
AS 通常可选,最好使用它
执行算数计算
SELECT prod_price * 1 + 2 - 1 / 3 % 2
FROM Products;
8 使用函数处理数据
函数
上面的RTRIM就是一个函数。
与SQL语句不一样,SQL函数不是可移植的。意味着为特定SQL实现编写的代码在其他实现中可能不能用。
许多SQL程序员不在城使用特定于实现的功能。虽然这样做有好处,但有时候并不利于应用程序的性能。