auto commit
This commit is contained in:
parent
67d8714471
commit
dcae17b9d9
177
notes/SQL.md
177
notes/SQL.md
|
@ -201,7 +201,7 @@ WHERE col IS NULL;
|
|||
| `=` `<` `>` | 等于 小于 大于 |
|
||||
| `<>` `!=` | 不等于 |
|
||||
| `<=` `!>` | 小于等于 |
|
||||
| `>=` `!<` | 大于等于 |
|
||||
| `>=` `!<` | 大于等于 |
|
||||
| `BETWEEN` | 在两个值之间 |
|
||||
| `IS NULL` | 为 NULL 值 |
|
||||
|
||||
|
@ -228,7 +228,7 @@ WHERE col IS NULL;
|
|||
```sql
|
||||
SELECT *
|
||||
FROM mytable
|
||||
WHERE col LIKE '[^AB]%' -- 不以 A 和 B 开头的任意文本
|
||||
WHERE col LIKE '[^AB]%'; -- 不以 A 和 B 开头的任意文本
|
||||
```
|
||||
|
||||
不要滥用通配符,通配符位于开头处匹配会非常慢。
|
||||
|
@ -240,15 +240,15 @@ WHERE col LIKE '[^AB]%' -- 不以 A 和 B 开头的任意文本
|
|||
计算字段通常需要使用 **AS** 来取别名,否则输出的时候字段名为计算表达式。
|
||||
|
||||
```sql
|
||||
SELECT col1*col2 AS alias
|
||||
FROM mytable
|
||||
SELECT col1 * col2 AS alias
|
||||
FROM mytable;
|
||||
```
|
||||
|
||||
**CONCAT()** 用于连接两个字段。许多数据库会使用空格把一个值填充为列宽,因此连接的结果会出现一些不必要的空格,使用 **TRIM()** 可以去除首尾空格。
|
||||
|
||||
```sql
|
||||
SELECT CONCAT(TRIM(col1), ' (', TRIM(col2), ')')
|
||||
FROM mytable
|
||||
SELECT CONCAT(TRIM(col1), '(', TRIM(col2), ')') AS concat_col
|
||||
FROM mytable;
|
||||
```
|
||||
|
||||
# 十二、函数
|
||||
|
@ -259,11 +259,11 @@ FROM mytable
|
|||
|
||||
| 函数 | 说明 |
|
||||
| :---: | :---: |
|
||||
| LEFT() RIGHT() | 左边或者右边的字符 |
|
||||
| LOWER() UPPER() | 转换为小写或者大写 |
|
||||
| LTRIM() RTIM() | 去除左边或者右边的空格 |
|
||||
| LENGTH() | 长度 |
|
||||
| SOUNDEX() | 转换为语音值 |
|
||||
| `LEFT()` `RIGHT()` | 左边或者右边的字符 |
|
||||
| `LOWER()` `UPPER()` | 转换为小写或者大写 |
|
||||
| `LTRIM()` `RTIM()` | 去除左边或者右边的空格 |
|
||||
| `LENGTH()` | 长度 |
|
||||
| `SOUNDEX()` | 转换为语音值 |
|
||||
|
||||
其中, **SOUNDEX()** 可以将一个字符串转换为描述其语音表示的字母数字模式。
|
||||
|
||||
|
@ -280,23 +280,23 @@ WHERE SOUNDEX(col1) = SOUNDEX('apple')
|
|||
|
||||
|函 数 | 说 明|
|
||||
| :---: | :---: |
|
||||
| AddDate() | 增加一个日期(天、周等)|
|
||||
| AddTime() | 增加一个时间(时、分等)|
|
||||
| CurDate() | 返回当前日期 |
|
||||
| CurTime() | 返回当前时间 |
|
||||
| Date() |返回日期时间的日期部分|
|
||||
| DateDiff() |计算两个日期之差|
|
||||
| Date_Add() |高度灵活的日期运算函数|
|
||||
| Date_Format() |返回一个格式化的日期或时间串|
|
||||
| Day()| 返回一个日期的天数部分|
|
||||
| DayOfWeek() |对于一个日期,返回对应的星期几|
|
||||
| Hour() |返回一个时间的小时部分|
|
||||
| Minute() |返回一个时间的分钟部分|
|
||||
| Month() |返回一个日期的月份部分|
|
||||
| Now() |返回当前日期和时间|
|
||||
| Second() |返回一个时间的秒部分|
|
||||
| Time() |返回一个日期时间的时间部分|
|
||||
| Year() |返回一个日期的年份部分|
|
||||
| `AddDate()` | 增加一个日期(天、周等)|
|
||||
| `AddTime()` | 增加一个时间(时、分等)|
|
||||
| `CurDate()` | 返回当前日期 |
|
||||
| `CurTime()` | 返回当前时间 |
|
||||
| `Date()` |返回日期时间的日期部分|
|
||||
| `DateDiff()` |计算两个日期之差|
|
||||
| `Date_Add()` |高度灵活的日期运算函数|
|
||||
| `Date_Format()` |返回一个格式化的日期或时间串|
|
||||
| `Day()`| 返回一个日期的天数部分|
|
||||
| `DayOfWeek()` |对于一个日期,返回对应的星期几|
|
||||
| `Hour()` |返回一个时间的小时部分|
|
||||
| `Minute()` |返回一个时间的分钟部分|
|
||||
| `Month()` |返回一个日期的月份部分|
|
||||
| `Now()` |返回当前日期和时间|
|
||||
| `Second()` |返回一个时间的秒部分|
|
||||
| `Time()` |返回一个日期时间的时间部分|
|
||||
| `Year()` |返回一个日期的年份部分|
|
||||
|
||||
```sql
|
||||
mysql> SELECT NOW();
|
||||
|
@ -310,25 +310,25 @@ mysql> SELECT NOW();
|
|||
|
||||
| 函数 | 说明 |
|
||||
| :---: | :---: |
|
||||
| SIN() | 正弦 |
|
||||
| COS() | 余弦 |
|
||||
| TAN() | 正切 |
|
||||
| ABS() | 绝对值 |
|
||||
| SQRT() | 平方根 |
|
||||
| MOD() | 余数 |
|
||||
| EXP() | 指数 |
|
||||
| PI() | 圆周率 |
|
||||
| RAND() | 随机数 |
|
||||
| `SIN()` | 正弦 |
|
||||
| `COS()` | 余弦 |
|
||||
| `TAN()` | 正切 |
|
||||
| `ABS()` | 绝对值 |
|
||||
| `SQRT()` | 平方根 |
|
||||
| `MOD()` | 余数 |
|
||||
| `EXP()` | 指数 |
|
||||
| `PI()` | 圆周率 |
|
||||
| `RAND()` | 随机数 |
|
||||
|
||||
## 汇总
|
||||
|
||||
|函 数 |说 明|
|
||||
| :---: | :---: |
|
||||
| AVG() | 返回某列的平均值 |
|
||||
| COUNT() | 返回某列的行数 |
|
||||
| MAX() | 返回某列的最大值 |
|
||||
| MIN() | 返回某列的最小值 |
|
||||
| SUM() |返回某列值之和 |
|
||||
| `AVG()` | 返回某列的平均值 |
|
||||
| `COUNT()` | 返回某列的行数 |
|
||||
| `MAX()` | 返回某列的最大值 |
|
||||
| `MIN()` | 返回某列的最小值 |
|
||||
| `SUM()` |返回某列值之和 |
|
||||
|
||||
AVG() 会忽略 NULL 行。
|
||||
|
||||
|
@ -345,7 +345,7 @@ FROM mytable
|
|||
|
||||
可以对同一分组数据使用汇总函数进行处理,例如求分组数据的平均值等。
|
||||
|
||||
指定的分组字段除了能按该字段进行分组,也会自动按按该字段进行排序。
|
||||
指定的分组字段除了能按该字段进行分组,也会自动按该字段进行排序。
|
||||
|
||||
```sql
|
||||
SELECT col, COUNT(*) AS num
|
||||
|
@ -353,7 +353,7 @@ FROM mytable
|
|||
GROUP BY col;
|
||||
```
|
||||
|
||||
GROUP BY 按分组字段进行排序,ORDER BY 也可以以汇总字段来进行排序。
|
||||
GROUP BY 自动按分组字段进行排序,ORDER BY 也可以按汇总字段来进行排序。
|
||||
|
||||
```sql
|
||||
SELECT col, COUNT(*) AS num
|
||||
|
@ -416,17 +416,17 @@ ORDER BY cust_name;
|
|||
内连接又称等值连接,使用 INNER JOIN 关键字。
|
||||
|
||||
```sql
|
||||
select a, b, c
|
||||
from A inner join B
|
||||
on A.key = B.key
|
||||
SELECT a, b, c
|
||||
FROM A INNER JOIN B
|
||||
ON A.key = B.key;
|
||||
```
|
||||
|
||||
可以不明确使用 INNER JOIN,而使用普通查询并在 WHERE 中将两个表中要连接的列用等值方法连接起来。
|
||||
|
||||
```sql
|
||||
select a, b, c
|
||||
from A, B
|
||||
where A.key = B.key
|
||||
SELECT a, b, c
|
||||
FROM A, B
|
||||
WHERE A.key = B.key;
|
||||
```
|
||||
|
||||
在没有条件语句的情况下返回笛卡尔积。
|
||||
|
@ -440,21 +440,21 @@ where A.key = B.key
|
|||
子查询版本
|
||||
|
||||
```sql
|
||||
select name
|
||||
from employee
|
||||
where department = (
|
||||
select department
|
||||
from employee
|
||||
where name = "Jim");
|
||||
SELECT name
|
||||
FROM employee
|
||||
WHERE department = (
|
||||
SELECT department
|
||||
FROM employee
|
||||
WHERE name = "Jim");
|
||||
```
|
||||
|
||||
自连接版本
|
||||
|
||||
```sql
|
||||
select e1.name
|
||||
from employee as e1, employee as e2
|
||||
where e1.department = e2.department
|
||||
and e2.name = "Jim";
|
||||
SELECT e1.name
|
||||
FROM employee AS e1, employee AS e2
|
||||
WHERE e1.department = e2.department
|
||||
AND e2.name = "Jim";
|
||||
```
|
||||
|
||||
连接一般比子查询的效率高。
|
||||
|
@ -466,8 +466,8 @@ where e1.department = e2.department
|
|||
内连接和自然连接的区别:内连接提供连接的列,而自然连接自动连接所有同名列。
|
||||
|
||||
```sql
|
||||
select *
|
||||
from employee natural join department;
|
||||
SELECT *
|
||||
FROM employee NATURAL JOIN department;
|
||||
```
|
||||
|
||||
## 外连接
|
||||
|
@ -477,19 +477,19 @@ from employee natural join department;
|
|||
检索所有顾客的订单信息,包括还没有订单信息的顾客。
|
||||
|
||||
```sql
|
||||
select Customers.cust_id, Orders.order_num
|
||||
from Customers left outer join Orders
|
||||
on Customers.cust_id = Orders.cust_id;
|
||||
SELECT Customers.cust_id, Orders.order_num
|
||||
FROM Customers LEFT OUTER JOIN Orders
|
||||
ON Customers.cust_id = Orders.cust_id;
|
||||
```
|
||||
|
||||
如果需要统计顾客的订单数,使用聚集函数。
|
||||
|
||||
```sql
|
||||
select Customers.cust_id,
|
||||
COUNT(Orders.order_num) as num_ord
|
||||
from Customers left outer join Orders
|
||||
on Customers.cust_id = Orders.cust_id
|
||||
group by Customers.cust_id;
|
||||
SELECT Customers.cust_id,
|
||||
COUNT(Orders.order_num) AS num_ord
|
||||
FROM Customers LEFT OUTER JOIN Orders
|
||||
ON Customers.cust_id = Orders.cust_id
|
||||
GROUP BY Customers.cust_id;
|
||||
```
|
||||
|
||||
# 十六、组合查询
|
||||
|
@ -514,18 +514,20 @@ WHERE col =2;
|
|||
|
||||
# 十七、视图
|
||||
|
||||
视图是虚拟的表,本身不包含数据,也就不能对其进行索引操作。对视图的操作和对普通表的操作一样。
|
||||
视图是虚拟的表,本身不包含数据,也就不能对其进行索引操作。
|
||||
|
||||
对视图的操作和对普通表的操作一样。
|
||||
|
||||
视图具有如下好处:
|
||||
|
||||
1. 简化复杂的 SQL 操作,比如复杂的联结;
|
||||
1. 简化复杂的 SQL 操作,比如复杂的连接;
|
||||
2. 只使用实际表的一部分数据;
|
||||
3. 通过只给用户访问视图的权限,保证数据的安全性;
|
||||
4. 更改数据格式和表示。
|
||||
|
||||
```sql
|
||||
CREATE VIEW myview AS
|
||||
SELECT Concat(col1, col2) AS concat_col, col3*col4 AS count_col
|
||||
SELECT Concat(col1, col2) AS concat_col, col3*col4 AS compute_col
|
||||
FROM mytable
|
||||
WHERE col5 = val;
|
||||
```
|
||||
|
@ -534,14 +536,12 @@ WHERE col5 = val;
|
|||
|
||||
存储过程可以看成是对一系列 SQL 操作的批处理;
|
||||
|
||||
## 使用存储过程的好处
|
||||
使用存储过程的好处
|
||||
|
||||
1. 代码封装,保证了一定的安全性;
|
||||
2. 代码复用;
|
||||
3. 由于是预先编译,因此具有很高的性能。
|
||||
|
||||
## 创建存储过程
|
||||
|
||||
命令行中创建存储过程需要自定义分隔符,因为命令行是以 ; 为结束符,而存储过程中也包含了分号,因此会错误把这部分分号当成是结束符,造成语法错误。
|
||||
|
||||
包含 in、out 和 inout 三种参数。
|
||||
|
@ -590,7 +590,7 @@ create procedure myprocedure(out ret int)
|
|||
|
||||
declare mycursor cursor for
|
||||
select col1 from mytable;
|
||||
# 定义了一个continue handler,当 sqlstate '02000' 这个条件出现时,会执行 set done = 1
|
||||
# 定义了一个 continue handler,当 sqlstate '02000' 这个条件出现时,会执行 set done = 1
|
||||
declare continue handler for sqlstate '02000' set done = 1;
|
||||
|
||||
open mycursor;
|
||||
|
@ -607,7 +607,7 @@ create procedure myprocedure(out ret int)
|
|||
|
||||
# 二十、触发器
|
||||
|
||||
触发器会在某个表执行以下语句时而自动执行:DELETE、INSERT、UPDATE
|
||||
触发器会在某个表执行以下语句时而自动执行:DELETE、INSERT、UPDATE。
|
||||
|
||||
触发器必须指定在语句执行之前还是之后自动执行,之前执行使用 BEFORE 关键字,之后执行使用 AFTER 关键字。BEFORE 用于数据验证和净化。
|
||||
|
||||
|
@ -617,8 +617,7 @@ INSERT 触发器包含一个名为 NEW 的虚拟表。
|
|||
CREATE TRIGGER mytrigger AFTER INSERT ON mytable
|
||||
FOR EACH ROW SELECT NEW.col into @result;
|
||||
|
||||
-- 获取结果
|
||||
SELECT @result;
|
||||
SELECT @result; -- 获取结果
|
||||
```
|
||||
|
||||
DELETE 触发器包含一个名为 OLD 的虚拟表,并且是只读的。
|
||||
|
@ -627,7 +626,7 @@ UPDATE 触发器包含一个名为 NEW 和一个名为 OLD 的虚拟表,其中
|
|||
|
||||
可以使用触发器来进行审计跟踪,把修改记录到另外一张表中。
|
||||
|
||||
MySQL 不允许在触发器中使用 CALL 语句 ,也就是不能调用存储过程。
|
||||
MySQL 不允许在触发器中使用 CALL 语句,也就是不能调用存储过程。
|
||||
|
||||
# 二十一、事务处理
|
||||
|
||||
|
@ -689,7 +688,7 @@ USE mysql;
|
|||
SELECT user FROM user;
|
||||
```
|
||||
|
||||
## 创建账户
|
||||
**创建账户**
|
||||
|
||||
```sql
|
||||
CREATE USER myuser IDENTIFIED BY 'mypassword';
|
||||
|
@ -697,25 +696,25 @@ CREATE USER myuser IDENTIFIED BY 'mypassword';
|
|||
|
||||
新创建的账户没有任何权限。
|
||||
|
||||
## 修改账户名
|
||||
**修改账户名**
|
||||
|
||||
```sql
|
||||
RENAME myuser TO newuser;
|
||||
```
|
||||
|
||||
## 删除账户
|
||||
**删除账户**
|
||||
|
||||
```sql
|
||||
DROP USER myuser;
|
||||
```
|
||||
|
||||
## 查看权限
|
||||
**查看权限**
|
||||
|
||||
```sql
|
||||
SHOW GRANTS FOR myuser;
|
||||
```
|
||||
|
||||
## 授予权限
|
||||
**授予权限**
|
||||
|
||||
```sql
|
||||
GRANT SELECT, INSERT ON mydatabase.* TO myuser;
|
||||
|
@ -723,7 +722,7 @@ GRANT SELECT, INSERT ON mydatabase.* TO myuser;
|
|||
|
||||
账户用 username@host 的形式定义,username@% 使用的是默认主机名。
|
||||
|
||||
## 删除权限
|
||||
**删除权限**
|
||||
|
||||
```sql
|
||||
REVOKE SELECT, INSERT ON mydatabase.* FROM myuser;
|
||||
|
@ -737,12 +736,12 @@ GRANT 和 REVOKE 可在几个层次上控制访问权限:
|
|||
- 特定的列;
|
||||
- 特定的存储过程。
|
||||
|
||||
## 更改密码
|
||||
**更改密码**
|
||||
|
||||
必须使用 Password() 函数
|
||||
|
||||
```sql
|
||||
SET PASSWROD FOR myuser = Password('newpassword');
|
||||
SET PASSWROD FOR myuser = Password('new_password');
|
||||
```
|
||||
|
||||
# 参考资料
|
||||
|
|
Loading…
Reference in New Issue
Block a user