SQL 基础
查询
查询步骤:
- 选择要查询的库
USE db - 使用
SELECT语句
基本语句:
SELECT查询的列FROM查询的表WHERE筛选条件ORDER BY排序条件
| customer_id | first_name |
|---|---|
| 1 | Babara |
SELECT 子句
选择查询的列, * 表示查询所有列
| customer_id | first_name | last_name | birth_date | phone | address | city | state | points |
|---|---|---|---|---|---|---|---|---|
| 2 | Ines | Brushfield | 1986-04-13 | 804-427-9456 | 14187 Commercial Trail | Hampton | VA | 947 |
SELECT 可以对列进行算数运算
| points | points * 10 + 100 |
|---|---|
| 2967 | 29770 |
列可以使用别名,使用 AS 关键字,有空格的列名使用引号包裹
| points | points discount |
|---|---|
| 2967 | 2670.3 |
使用 DISTINCT 关键字可以删除列中的重复项
| points | points discount |
|---|---|
| 3675 | 3307.5 |
WHERE 子句
条件筛选
| customer_id | first_name | last_name | birth_date | phone | address | city | state | points |
|---|---|---|---|---|---|---|---|---|
| 5 | Clemmie | Betchley | 1973-11-07 | NULL | 5 Spohn Circle | Arlington | TX | 3675 |
| 6 | Elka | Twiddell | 1991-09-04 | 312-480-8498 | 7 Manley Drive | Chicago | IL | 3073 |
组合条件,支持 AND , OR , NOT , 多个逻辑运算符时, AND 优先级更高,最好用括号显示表达优先级
| customer_id | first_name | last_name | birth_date | phone | address | city | state | points |
|---|---|---|---|---|---|---|---|---|
| 6 | Elka | Twiddell | 1991-09-04 | 312-480-8498 | 7 Manley Drive | Chicago | IL | 3073 |
| order_id | product_id | quantity | unit_price |
|---|---|---|---|
| 6 | 1 | 4 | 8.65 |
IN 运算符判断是否在集合中
| customer_id | first_name | last_name | birth_date | phone | address | city | state | points |
|---|---|---|---|---|---|---|---|---|
| 2 | Ines | Brushfield | 1986-04-13 | 804-427-9456 | 14187 Commercial Trail | Hampton | VA | 947 |
| 4 | Ambur | Roseburgh | 1974-04-14 | 407-231-8017 | 30 Arapahoe Terrace | Orlando | FL | 457 |
| 8 | Thacher | Naseby | 1993-07-17 | 941-527-3977 | 538 Mosinee Center | Sarasota | FL | 205 |
BETWEEN 运算符判断是否在闭区间中
| customer_id | first_name | last_name | birth_date | phone | address | city | state | points |
|---|---|---|---|---|---|---|---|---|
| 1 | Babara | MacCaffrey | 1986-03-28 | 781-932-9754 | 0 Sage Terrace | Waltham | MA | 2273 |
| 3 | Freddi | Boagey | 1985-02-07 | 719-724-7869 | 251 Springs Junction | Colorado Springs | CO | 2967 |
LIKE 运算符进行字符串模式匹配, % 匹配任意字符, _ 匹配单个任意字符
| customer_id | first_name | last_name | birth_date | phone | address | city | state | points |
|---|---|---|---|---|---|---|---|---|
| 2 | Ines | Brushfield | 1986-04-13 | 804-427-9456 | 14187 Commercial Trail | Hampton | VA | 947 |
| 3 | Freddi | Boagey | 1985-02-07 | 719-724-7869 | 251 Springs Junction | Colorado Springs | CO | 2967 |
| 5 | Clemmie | Betchley | 1973-11-07 | NULL | 5 Spohn Circle | Arlington | TX | 3675 |
REGEXP 运算符,进行正则匹配,匹配相关可以看 正则表达式
| customer_id | first_name | last_name | birth_date | phone | address | city | state | points |
|---|---|---|---|---|---|---|---|---|
| 2 | Ines | Brushfield | 1986-04-13 | 804-427-9456 | 14187 Commercial Trail | Hampton | VA | 947 |
IS NULL 运算符,判断是否为 NULL
| customer_id | first_name | last_name | birth_date | phone | address | city | state | points |
|---|---|---|---|---|---|---|---|---|
| 5 | Clemmie | Betchley | 1973-11-07 | NULL | 5 Spohn Circle | Arlington | TX | 3675 |
ORDER BY 子句
ORDER BY 子句指定一列或多列排序,每列后面可跟 DESC 表示降序
| customer_id | first_name | last_name | birth_date | phone | address | city | state | points |
|---|---|---|---|---|---|---|---|---|
| 2 | Ines | Brushfield | 1986-04-13 | 804-427-9456 | 14187 Commercial Trail | Hampton | VA | 947 |
| 5 | Clemmie | Betchley | 1973-11-07 | NULL | 5 Spohn Circle | Arlington | TX | 3675 |
| 7 | Ilene | Dowson | 1964-08-30 | 615-641-4759 | 50 Lillian Crossing | Nashville | TN | 1672 |
| 1 | Babara | MacCaffrey | 1986-03-28 | 781-932-9754 | 0 Sage Terrace | Waltham | MA | 2273 |
| 6 | Elka | Twiddell | 1991-09-04 | 312-480-8498 | 7 Manley Drive | Chicago | IL | 3073 |
| 10 | Levy | Mynett | 1969-10-13 | 404-246-3370 | 68 Lawn Avenue | Atlanta | GA | 796 |
| 4 | Ambur | Roseburgh | 1974-04-14 | 407-231-8017 | 30 Arapahoe Terrace | Orlando | FL | 457 |
| 8 | Thacher | Naseby | 1993-07-17 | 941-527-3977 | 538 Mosinee Center | Sarasota | FL | 205 |
| 3 | Freddi | Boagey | 1985-02-07 | 719-724-7869 | 251 Springs Junction | Colorado Springs | CO | 2967 |
| 9 | Romola | Rumgay | 1992-05-23 | 559-181-3744 | 3520 Ohio Trail | Visalia | CA | 1486 |
MySQL 支持 ORDER BY 使用不在 SELECT 里的列进行排序,支持别名列,列做算数运算
| order_id | product_id | quantity | unit_price | total_price |
|---|---|---|---|---|
| 2 | 1 | 2 | 9.10 | 18.20 |
| 2 | 4 | 4 | 1.66 | 6.64 |
| 2 | 6 | 2 | 2.94 | 5.88 |
LIMIT 子句
LIMIT 子句限制返回的行数
单个数字表示从第一行开始显示 n 行
| customer_id | first_name | last_name |
|---|---|---|
| 1 | Babara | MacCaffrey |
| 2 | Ines | Brushfield |
| 3 | Freddi | Boagey |
LIMIT 可以指定跳过多少行
| customer_id | first_name | last_name |
|---|---|---|
| 7 | Ilene | Dowson |
| 8 | Thacher | Naseby |
| 9 | Romola | Rumgay |
连接
连接相关的原理参考 数据库中的连接操作
两表内连接
JOIN 子句连接两个表, ON 表示连接条件
| order_id | first_name | last_name |
|---|---|---|
| 4 | Ines | Brushfield |
| 7 | Ines | Brushfield |
| 5 | Clemmie | Betchley |
| 8 | Clemmie | Betchley |
| 1 | Elka | Twiddell |
| 10 | Elka | Twiddell |
| 2 | Ilene | Dowson |
| 3 | Thacher | Naseby |
| 6 | Levy | Mynett |
| 9 | Levy | Mynett |
给列加上数据库名称前缀就能跨数据库连接
| order_id | product_id |
|---|---|
| 2 | 1 |
| 6 | 1 |
自连接
表可以自连接,同一个表要取不同的别名
| employee_id | reports_to | first_name | manager |
|---|---|---|---|
| 33391 | 37270 | D’arcy | Yovonnda |
| 37851 | 37270 | Sayer | Yovonnda |
| 40448 | 37270 | Mindy | Yovonnda |
多表连接
使用多个 join 句子
| order_id | customer_id | status | first_name | last_name |
|---|---|---|---|---|
| 1 | 6 | 1 | Elka | Twiddell |
| 2 | 7 | 2 | Ilene | Dowson |
| 3 | 8 | 1 | Thacher | Naseby |
复合连接条件
当表中有复合主键时,可以用复合连接条件确定具体的列
外连接
左外连接:除了满足连接条件的数据,还包括左表的所有数据右外连接:除了满足连接条件的数据,还包括右表的所有数据
| customer_id | first_name | order_id |
|---|---|---|
| 1 | Babara | NULL |
| 2 | Ines | 4 |
| 2 | Ines | 7 |
1 不满足连接条件,但是也在查询结果中
| customer_id | first_name | order_id |
|---|---|---|
| 1 | Babara | NULL |
| 2 | Ines | 4 |
| 2 | Ines | 7 |
右外连接,换了查表顺序得到相同结果
外连接同样可以多表连接
| customer_id | first_name | order_id | shipper |
|---|---|---|---|
| 1 | Babara | NULL | NULL |
| 2 | Ines | 4 | NULL |
| 2 | Ines | 7 | Mraz, Renner and Nolan |
| 3 | Freddi | NULL | NULL |
| 4 | Ambur | NULL | NULL |
| 5 | Clemmie | 5 | Satterfield LLC |
| 5 | Clemmie | 8 | NULL |
| 6 | Elka | 1 | NULL |
| 6 | Elka | 10 | Schinner-Predovic |
| 7 | Ilene | 2 | Mraz, Renner and Nolan |
外连接同样可以自连接
| employee_id | first_name | manager |
|---|---|---|
| 33391 | D’arcy | Yovonnda |
| 37270 | Yovonnda | NULL |
| 37851 | Sayer | Yovonnda |
USING 子句
如果 JOIN 使用的连接条件列名相同,可以使用 USING 代替 ON
| order_id | first_name | last_name |
|---|---|---|
| 4 | Ines | Brushfield |
| 7 | Ines | Brushfield |
| 5 | Clemmie | Betchley |
自然连接
NATURE JOIN 不指定连接条件,由数据库自己决定
交叉连接
CROSS JOIN 两张表做笛卡尔积,适合列出所有的排列组合,比如有大中小的型号表和各种颜色的颜色表,查出型号和颜色的所有组合
联合
UNION 可以将多个 SELECT 查询结果合并到一张表
| |
| customer_id | first_name | points | type |
|---|---|---|---|
| 4 | Ambur | 457 | Bronze |
| 1 | Babara | 2273 | Silver |
| 5 | Clemmie | 3675 | Gold |
| 6 | Elka | 3073 | Gold |
| 3 | Freddi | 2967 | Silver |
| 7 | Ilene | 1672 | Bronze |
| 2 | Ines | 947 | Bronze |
| 10 | Levy | 796 | Bronze |
| 9 | Romola | 1486 | Bronze |
| 8 | Thacher | 205 | Bronze |
插入
插入单行
使用 INSERT INTO 语句插入单行
插入多行
VALUES 后跟多个括号
多表插入
使用 LAST_INSERT_ID() 函数可以获取最后自增的 ID
复制表
使用 CREATE TABLE name AS
第二个 SELECT 称为子查询,也可以用在 INSERT 语句中,将查询到达数据插入 orders_archive 中
更新
使用 UPDATE 语句更新一行或多行数据
多行数据时使用 WHERE 语句选出多行即可,比如 WHERE invoice_id IN (3, 4, 5)
同样可以用 SELECT 作为子查询条件
删除
使用 DELETE FROM 语句删除表中的数据,用 WHERE 选择要删除的行
同样可以使用子查询
聚合函数
聚合函数可以对查询的数据进行计算并产生一个值,比如 MAX() MIN() AVG() SUM() COUNT() 等,只会计算非空的数据
| MIN | MAX | AVG | SUM | COUNT |
|---|---|---|---|---|
| 101.79 | 189.12 | 152.388235 | 2590.60 | 17 |
GROUP BY
GROUP BY 可以将数据安装指定列分组,分组后每一组进行聚合
| client_id | total |
|---|---|
| 5 | 980.02 |
| 1 | 802.89 |
| 3 | 705.90 |
| 2 | 101.79 |
也可以多列分组,结果是每一列的组合
| date | name | total_payments |
|---|---|---|
| 2019-01-03 | Credit Card | 74.55 |
| 2019-01-08 | Cash | 10.00 |
| 2019-01-08 | Credit Card | 32.77 |
| 2019-01-11 | Credit Card | 0.03 |
| 2019-01-15 | Credit Card | 148.41 |
| 2019-01-26 | Credit Card | 87.44 |
| 2019-02-12 | Credit Card | 8.18 |
HAVING 子句
HAVING 子句在 GROUP BY 分组后进行筛选
| client_id | total |
|---|---|
| 5 | 980.02 |
| 1 | 802.89 |
| 3 | 705.90 |
WITH ROLLUP
增加一行,对分组的数据做一次总计,只有 Mysql 有
| name | total_amount |
|---|---|
| Cash | 10.00 |
| Credit Card | 351.38 |
| NULL | 361.38 |
复杂查询
子查询返回值用于比较
| salary |
|---|
| 98926 |
| 94860 |
| 110150 |
子查询返回一列用 IN 判断
| client_id |
|---|
| 4 |
子查询返回一列值用 ALL 判断
| invoice_id | invoice_total |
|---|---|
| 2 | 175.32 |
| 5 | 169.36 |
| 8 | 189.12 |
| 9 | 172.17 |
| 18 | 180.17 |
上面的查询可以使用 MAX() 改写
类似还有 ANY 和 SOME 关键字,比如 = ANY(1, 2, 3) 表示等于 1,2,3 中的任意一个
相关子查询
子查询用到了父查询的列信息
| invoice_id |
|---|
| 2 |
| 4 |
| 5 |
| 8 |
| 9 |
| 15 |
| 16 |
| 18 |
EXIST 运算符
EXIST 判断是否存在
| client_id | name |
|---|---|
| 1 | Vinte |
| 2 | Myworks |
| 3 | Yadel |
| 5 | Topiclounge |
SELECT 中的子查询
子查询也可以用在 SELECT 列中
| client_id | name | total | avger | diff |
|---|---|---|---|---|
| 1 | Vinte | 802.89 | 152.388235 | 650.501765 |
| 2 | Myworks | 101.79 | 152.388235 | -50.598235 |
| 3 | Yadel | 705.90 | 152.388235 | 553.511765 |
| 4 | Kwideo | NULL | 152.388235 | NULL |
| 5 | Topiclounge | 980.02 | 152.388235 | 827.631765 |
FROM 中的子查询
子查询可以用在 FROM 中,当成一个虚拟的表
| |
| client_id | name | diff |
|---|---|---|
| 1 | Vinte | 650.501765 |
| 2 | Myworks | -50.598235 |
| 3 | Yadel | 553.511765 |
| 5 | Topiclounge | 827.631765 |