0%

Mosh教程SQL:重学SQL

前言:

我的SQL功底不行,所以重新找了一份教程来学习,希望能够更加的系统的学习。
视频在B站上,有非常热心的同学翻译成中文了:
https://www.bilibili.com/video/BV1UE41147KC
还有一些小伙伴的笔记:
课程:Mosh_完全掌握SQL【笔记】

随笔记录:

我就不需要重复安装了(还是重装了一边),跳过。

学习时间:

  • p1-p10:2.5小时(包括重装MYSQL) 2022-11-8
  • p11-p17 2小时 2022-11-9

创建数据库,直接用他的SQL备份文件恢复。

踩坑1:

utf8mb4_0900_ai_ci 是mysql8以后支持的语法。
解决方案:修改utf8mb4_0900_ai_ci为utf8mb4_unicode_ci或者utf8mb4_general_ci。 答案出处

示范:

1
2
3
4
5
6
7
8
9
10
11
12
# 选中数据库
USE sql_store;

# 查询表中所有数据
SELECT *
FROM customers;

# 子句是可选的,如where
SELECT *
FROM customers
WHERE `customer_id`=2;

选择SELECT子句:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 可以用具体的列(多个逗号隔开)来代替*所有列
SELECT `first_name`,`last_name`
FROM customers;

# 改变顺序影响结果的显示
SELECT `last_name`,`first_name`
FROM customers;

# 可以进行算术运算
SELECT `last_name`,`first_name`,`points`+10
FROM customers;

# 其他的算术运算(可以换行)
SELECT
`last_name`,
`first_name`,
`points`,
`points`+10,
`points`-10,
`points`*10,
`points`/10,
`points`%10
FROM customers;

# 算术用括号表示优先级,AS 起别名
SELECT
`last_name`,
`first_name`,
`points`,
(`points`+10)*2 AS count_poins
FROM customers;

# 加上DISTINCT去除重复项
SELECT DISTINCT state
FROM customers;

# 练习:
SELECT
`name`,
`unit_price`,
`unit_price`*1.1 AS new_price
FROM `products`;

WHERE子句:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# WHERE后面可以加上条件
SELECT *
FROM `customers`
WHERE `points`>3000;

# 比较运算符 > < = <= >= != <>
# 字符串需要用引号,单双都可以
SELECT *
FROM `customers`
WHERE `state`='VA';

# <>表示不等于,等价于!=
SELECT *
FROM `customers`
WHERE `state`<>'VA';

# 日期也可以用于比较运算,'YYYY-MM-DD'
SELECT *
FROM `customers`
WHERE `birth_date`>'1990-01-01';

# 练习
SELECT *
FROM `orders`
WHERE `order_date`>='2019-01-01';

AND、OR、NOT运算符:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# AND用于连接两个条件,同真则真
SELECT *
FROM `customers`
WHERE `birth_date`>'1990-01-01' AND `points`>1000;

# OR用于连接两个条件,有真则真
SELECT *
FROM `customers`
WHERE `birth_date`>'1990-01-01' OR `points`>1000;

# 多个条件可以并用
SELECT *
FROM `customers`
WHERE `birth_date`>'1990-01-01' OR
(`points`>1000 AND `state`='VA');

# NOT表示取反
SELECT *
FROM `customers`
WHERE NOT (`birth_date`>'1990-01-01' OR `points`>1000);


# 练习:
SELECT *
FROM `order_items`
WHERE `order_id`=6 AND `quantity`*`unit_price`>30;

IN运算符:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# IN可以表示某个条件属于多个集合中的一个
SELECT *
FROM `customers`
WHERE `state` IN ('VA','FL','GA');

# NOTIN 可以并用,表示不属于
SELECT *
FROM `customers`
WHERE `state` NOT IN ('VA','FL','GA');

# 练习:
SELECT *
FROM `products`
WHERE `quantity_in_stock` IN (49,38,72);

BETWEEN运算符:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 原语句
SELECT *
FROM `customers`
WHERE `points`>=1000 AND `points`<=3000;

# BETWEEN运算符是简化语句
SELECT *
FROM `customers`
WHERE `points` BETWEEN 1000 AND 3000;

# 练习:
SELECT *
FROM `customers`
WHERE `birth_date` BETWEEN '1990-01-01' AND '2000-01-01';

LIKE运算符:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# LIKE运算符比较字符串中有无对应内容,以b开头
SELECT *
FROM `customers`
WHERE `last_name` LIKE 'b%';

# %表示可以有多个,如姓名含有b应该写为
SELECT *
FROM `customers`
WHERE `last_name` LIKE '%b%';

# 以y结尾
SELECT *
FROM `customers`
WHERE `last_name` LIKE '%y';

# 下划线代表单个字母
SELECT *
FROM `customers`
WHERE `last_name` LIKE '_____y';

# 练习:
SELECT *
FROM `customers`
WHERE `address` LIKE '%trail%' OR
`address` LIKE '%avenue%';

# 同样可以加上NOT
SELECT *
FROM `customers`
WHERE`phone` NOT LIKE '%9';

REGEXP运算符:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# 获取名字中有field的 原语句
SELECT *
FROM `customers`
WHERE `last_name` LIKE '%field%';

# REGEXP运算符表示正则表达式
SELECT *
FROM `customers`
WHERE `last_name` REGEXP 'field';

# ^表示开头,$表示结尾
SELECT *
FROM `customers`
WHERE `last_name` REGEXP 'field$';

# |表示或者
SELECT *
FROM `customers`
WHERE `last_name` REGEXP 'field|mac';

# []里面内容表示在前面可能出现的
# 下面可能是ge ie me
SELECT *
FROM `customers`
WHERE `last_name` REGEXP '[gim]e';

# 也可以在[]内使用-表示从A到H
SELECT *
FROM `customers`
WHERE `last_name` REGEXP '[a-h]e';

# 练习:
SELECT *
FROM `customers`
WHERE `first_name` REGEXP 'elka|ambur';

SELECT *
FROM `customers`
WHERE `last_name` REGEXP 'ey$|on$';

SELECT *
FROM `customers`
WHERE `last_name` REGEXP '^my|se';


SELECT *
FROM `customers`
WHERE `last_name` REGEXP 'b[ru]';

IS NULL 运算符:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 可以判断是否为NULL
SELECT *
FROM `customers`
WHERE `phone` IS NULL;

# 一样可以加上NOT,表示非NULL
SELECT *
FROM `customers`
WHERE `phone` IS NOT NULL;

# 练习:
SELECT *
FROM `orders`
WHERE `shipped_date` IS NULL;

ORDER BY 子句:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# ORDER BY排序,可以选择其他列作为排序依据
SELECT *
FROM `customers`
ORDER BY `first_name`;

# 加上DESC可以降序
SELECT *
FROM `customers`
ORDER BY `first_name` DESC;

# 可以同时处理多个排序条件
SELECT *
FROM `customers`
ORDER BY `state` DESC ,`first_name` DESC;

# 练习:
SELECT *,`quantity`*`unit_price` AS total_price
FROM `order_items`
WHERE `order_id`=2
ORDER BY total_price DESC;

LIMIT子句:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# LIMIT用于截断数据显示
SELECT *
FROM `customers`
LIMIT 3;

# 偏移量表示跳过N个,比如获取7-9个用户
SELECT *
FROM `customers`
LIMIT 6,3;

# 练习:获取积分排名前三的用户
SELECT *
FROM `customers`
ORDER BY `points` DESC
LIMIT 3;

总结:

本文记录了第二章,在单一表中检索数据。我把子句放在了同级目录,技巧放在下级目录中,方便以后忘记了再来复习会快速查找。