目录
一.写在前面
二.介绍
三.选择语句
四.内连接
五.列属性
一.写在前面
课程视频:【中字】SQL进阶教程 | 史上最易懂SQL教程!10小时零基础成长SQL大师!!_哔哩哔哩_bilibili
课程所需资料:
链接:https://pan.baidu.com/s/1xDsDWFLiRITYTT6HoFb7Tw
提取码:s5iz
二.介绍
数据库是用来存储数据的集合,一般用数据库管理系统(dbms)来进行管理,目前有两种dbms:
关系型(RDBMS)和非关系型(NoSQL)
前者是我们接下来会学习的,后者即没有表或者关系(例如在关系型中,每个产品都会有个价格;然而在非关系型中,产品与价格是拆分来来的)。
本课程使用的是mySQL,安装略(安装教程视频里有)。
红色框框点进去,就会弹出下面那个界面,输入在安装时设置的密码。
成功时会弹出下面的界面(噫!我成功啦):
下载视频课程后链接的zip文件,其中会有课程所需要的文件内容。点击新创建的connections,点击左上角(下图红色圈圈所圈的图案),引入 create-databases.sql 这个文件。
引入以后,需要先运行一下(点闪电)再刷新才会有schemas里面的东西。
三.选择语句
1.在单一表格中检索数据
mySQL中不区分大小写,建议关键字用大写的,数据内容用小写的。
* 代表everything ,想要什么就select什么。
2.选择子句
select 可以是任意表达式
加减乘除的优先级与数学中一样。as关键字是将某一列的名称改名,如下图
当state出现了两个VA,而我们只想要出现一个时,就使用distinct关键字。
练习:
SELECT name,
unit_price,
unit_price*1.1 AS 'new price'
FROM products
3.where关键字
练习:
假设我们现在在2019年,则代码如下:
SELECT *
FROM orders
WHERE order_date>='2019-01-01' AND order_date<='2019-12-30'
4.三个逻辑关键字
and -- &&
or -- ||
not -- !
5.in 关键字
多个元素选一个,只要有一个满足就是所选项
练习:
SELECT *
FROM products
WHERE quantity_in_stock IN (49,38,72)
-- in后内容是字符或者字符型数字,那么每个字符都需要加上单引号。(这就像C当中的char型数据)
6.between 关键字
可以类比成定义域
练习:
SELECT *
FROM customers
WHERE birth_date BETWEEN '1990-01-01' AND '2000-01-01'
7.like 关键字
该关键字是用来获取符合某一字符特性数据的
'%b%' -- 只要有b字母就行
'brush%' -- brush开头
'%y' -- y结尾就行
'_y' -- y前面只能有1个字符
'_____y' -- y前面有5个字符(前面5根下划线)
练习:
SELECT *
FROM customers
WHERE address LIKE '%TRAIL%' OR
address LIKE '%avenue%'OR
phone LIKE '%9'
8.regexp 关键字
关键字是regular expression的缩写,通常用来搜寻字符串。
WHERE address LIKE '%TRAIL%'
WHERE address REGEXP 'TRAIL'
上面两条语句的作用是一模一样的。
'^x' -- 以x开头
'x$' -- 以x结尾
'x|y' -- 包含 x 或者 y ( | 可以跟个好几个,并且 | 可以和 ^ 或者 $ 结合使用)
'[gim]e' -- 包含ge或ie或me的字符串
'[a-c]e' -- 包含ae或be或ce的字符串
9.is (not) null 关键字
表格中部分数据为空,该关键字就是用来把某些数据为空的信息提取出来,is not null 就是把某些数据非空的信息提取出来。
练习:
图
SELECT *
FROM orders
WHERE shipped_date IS NULL
10.order by 关键字
点击把手按钮,就可以跳转到设置页面。该页面可以设置默认的排序方式,删除某一列,添加新列等。最上面的那个图标是黄色的,因为它很特殊。它被叫做主键列,这一列中的值要能够唯一识别表中数据。(每个顾客的id只能是唯一的,因此id可以作为主键列)
order by xxx,yyy 以后,如果要让xxx降序排序的话可以在xxx后加上 desc,如果要让yyy降序排序的话可以在yyy后加上 desc
order by 也可以跟被as的元素(例如 select 10 as points,points也可以作为排序元素)
order by 1,2 -- 根据select关键字后紧跟着的第1个和第2个元素进行排序。(不推荐使用)
练习:
题目.在order_items中,只要order_id为2的,并且根据总价进行降序排序。
SELECT *
FROM order_items
WHERE order_id = 2
ORDER BY quantity*unit_price DESC
11.limit 子句
limit 3 -- 只提取整个数据库中的前3条信息
limit 6,3 -- 跳过数据库中前6条信息,提取后续3条信息
练习:
找到积分(points)最高的3位用户
SELECT *
FROM customers
ORDER BY points DESC
LIMIT 3
四.内连接
1.在多张表格中检索数据
在customers和orders两个表中,都存在customer_id这一项,因此该项就能够作为连接2个表的链条。
SELECT *
FROM orders
JOIN customers ON customers.customer_id = orders.customer_id
-- JOIN 需要连接过来的表 ON 两个表的哪一列关系可以行行对应
没有后面的on,那么只是简单地将customers表黏贴到orders表右边(并且会出现下图的情况);如果有了后面的on,不满足该关系的都会被删除。
(会有10*10 = 100 条不同数据)
当 select customer_id 时,必须要声明是要 orders.customer_id 还是 customers.customer_id
在 from 关键字 与 on 关键字 后的表格名称后面可以直接加上一个缩写,简单方便
SELECT *
FROM orders o
JOIN customers c
ON c.customer_id = o.customer_id
练习:
把products表连接到order_items表上,返回产品id、名字还有order_items表中的数量和单价。
SELECT name,oi.product_id,quantity,oi.unit_price
FROM order_items oi
JOIN products p
ON p.product_id = oi.product_id
2.跨数据库连接
练习:
如何把sql.inventory数据库中的products表格,连接到sql.store数据库中的order_items表格呢?
USE sql_store;
SELECT *
FROM order_items oi
JOIN sql_inventory.products p
ON oi.product_id = p.product_id
USE sql_inventory;
SELECT *
FROM sql_store.order_items oi
JOIN products p
ON oi.product_id = p.product_id
3.自连接
该表中,可以发现有很多的 reports_to(报告对象)是37270,那id为37270的就是老板。假设我们现在是那个老板,此时需要搞出一个员工表格,那么就可以通过自连接来实现。
此处需要注意的是,自连接必须要给到同一张表2个不同的别名,如果尝试用表格名作为ON后跟着的判断条件,则会出现下列报错
4.多表连接
注意:表连接尽量不要超过3张,过多的表连接会影响查询速度(会致使列过多,找不到自己需要的信息)
多表连接就是多次使用 join on 语句,然后把需要连接上来的表都通过该语句连接到目标表格。
练习:
打开sql_invoicing,把payment_methods表、clients表连接到payment表。
USE sql_invoicing;
SELECT *
FROM payments p
JOIN payment_methods pm
ON p.payment_method = pm.payment_method_id
JOIN clients c
ON p.client_id = c.client_id
5.复合连接条件
就是在ON后面多加一个判断依据,用关键字and连接下一个判断依据。
JOIN xxx
ON xxx.x = yyy.x
AND xxx.y = zzz.y
6.隐式连接语法
起到的也是join on 语句一样的作用,只是写法不一样。
7.外连接(难点)
提示:有没有发现左表其实就是被from的表,右表就是被join的表?
通过左连接让没有order_id的customer_id也显示出来,可以理解成将整个customers表都提取了出来。
右连接与一般连接结果相同,可以视作将整个orders表数据提取出来。
技巧:画个文氏图,JOIN ON 的是两者的交集,LEFT JOIN 是交集+剩下的左半部分,RIGHT JOIN 是交集+剩下的右半部分,不加ON的JOIN就是左右两个表的所有数据(可以看成 左并右)
并且 LEFT JOIN 就是针对FROM后面那个表而言的,RIGHT JOIN 就是针对JOIN后面那个表而言的。
练习:
把products全都提取一遍,要有卖出多少份+名字+id 3部分,一件都没卖出的也需要打印。
SELECT
p.product_id, -- 这里千万不能是oi.product_id,在order_items里,products_id = 7不存在,那么在SELECT时也会为NULL
p.name,
oi.quantity
FROM products p
LEFT JOIN order_items oi
ON oi.product_id = p.product_id
8.多表外连接
多表外连接就是多次使用外连接(e.g. left join + right join),同样不建议把太多表的数据外连接起来。
技巧:最好不要一会左连接,一会右连接,一会内连接。这会让自己和别人都看不懂写了点什么东西。
9.自外连接
自外连接就是在自连接的基础上,加上了外连接的。例如上一个自连接的例子,manager自己因为没有reports_to所以无法满足ON后条件,所以没有外连接的话就不会提取出来。用上left,就是把无论有没有reports_to都打印出来。
10.using子句
-- ON o.customer_id = c.customer_id
USING (customer_id)
上面两句代码的作用一模一样,using子句是用来简便代码的。(但需要确保两张表里都有using跟着的列名称)
如果要多个比较的话,就直接像下面一样即可。
USING (order_id,product_id)
11.自然连接
不太建议使用自然连接,因为时常会出现出乎意料的结果。
SELECT *
FROM orders o
NATURAL JOIN customers c
上面这条代码运行之后,数据库引擎会自己看着办,基于某条共同的列连接搞出一个表。
因为自然连接是把连接方式的权力交给了引擎,所以有点难以控制,因此不推荐使用。
12.交叉连接
SELECT *
FROM orders o
CROSS JOIN customers c
上述代码最终结果和只用join不加on的结果一样,也可以把cross join 的内容直接跟在from后面(如下所示)
SELECT *
FROM orders o
JOIN customers c
SELECT *
FROM orders o,customers c
13.联合(两面包夹芝士)
之前的连接都是结合多张表的列,联合是结合多张表的行。
练习:
假如我们把2019-01-01以后的order作为status=active的订单,把这之前的作为status=archived的订单,并且要把这两张表相结合起来。
首先进行第一次的select,把2019-01-01以后的订单提取出来
然后再把2019-01-01以前的提取出来,最后在两个select语句之间,加上一个union关键字,就能把两个表按行联合起来了。
全部代码如下:
USE sql_store;
SELECT
order_id,
order_date,
'Active' AS status
FROM orders
WHERE order_date >= '2019-01-01'
UNION
SELECT
order_id,
order_date,
'Archived' AS status
FROM orders
WHERE order_date < '2019-01-01'
注意:如果没有union关键字,两个select语句之间要有分号,因为这是两段不同的内容,如果有union关键字就不用。同时,select带的列必须是相同数量的,如果一个select了2列,一个select了1列,那么就会报错。最后,第一段查询了啥会决定最终的列名称(如下两图所示)。
五.列属性
1.列属性
点击三个按钮当中的工具按钮,就可以跳出该菜单。
表格介绍:
1.Column Name:列名称
2.Datatype:数据类型
INT(11) -- 整型数据,并且最多只能存放10位数字(11 - 1 = 10)
VARCHAR(50) -- 可变字符,存放字符数量会有不同,最多存放50个字符
CHAR(2) -- 不可变字符,存放字符数量需要相等,只能存放2个字符
假设现在有一列为CHAR(50),然后只用了5个字符,会自动插入45个空格符填满这列
3.PK:主键列,勾选项作为主键列存在。主键列的所有值只能是唯一的
4.NN:是否可以写入空值,未勾选项可以有空值
5.AI:自动递增,通常用在了主键列上
6.Default/Expression:当你没有提供任何值,会给有 'NULL'(表格中)的列直接填上空值NULL(数据表中),会给有 '0' (表格中)的列直接填上0
2.插入单行
INSERT INTO customers
VALUES(
DEFAULT,
'John',
'Smith',
'1990-01-01',
NULL,
'address',
'city',
'VA',
default)
default:默认给个值,一般性会根据表中最大的一条数据递增给出(这边出现那么怪的数字是特例,因为mysql是根据存在过的数字最大的那条数据给出默认值的,即使数字最大的那条数据被删除了)
NULL:必须得满足NN才可以用
插入单行以后,需要刷新一下表格,那行数据才会出现
3.插入多行
INSERT INTO shippers (name)
VALUES
('shipper1'),
('shipper2'),
('shipper3')
在insert语句最后可以加个括号,里面填入需要程序员来填写的数据列名称。剩下的一些列,mysql引擎会自动给出默认值(default值)。
4.插入分层行
INSERT INTO orders (customer_id,order_date,status)
VALUES(1,'2019-01-01',1);
INSERT INTO order_items
VALUES(LAST_INSERT_ID(),1,1,2),
(LAST_INSERT_ID(),2,3,4)
不难发现,上面的代码实现了新插入的行中order_id也出现在了两张不同的表上。
LAST_INSERT_ID:mysql内置函数之一,获取最后一条插入数据的id。
5.创建表复制(重点)
该节内容是要创建一张新表,并将一张表的部分数据复制到新表当中。
CREATE TABLE orders_archived
SELECT * FROM orders
通过上述代码,会创造出一个与orders完全一模一样的表格orders_archived
右键点击orders_archived表格,然后点击truncate table,会弹出上图窗口。接下来直接点击truncate,就能把orders_archived中的所有数据清空(如下图示)
我们现在要把2019-01-01以前的订单复制到新表中,代码如下:
INSERT INTO orders_archived
SELECT *
FROM orders
WHERE order_date < '2019-01-01'
同时,也可以在创建表格的时候直接将2019-01-01以后的订单排除掉,通过下述代码即可实现。
CREATE TABLE orders_archived2
SELECT *
FROM orders
WHERE order_date < '2019-01-01'
总结:创造新表然后复制进去的东西,其实就是query中select出来的东西。因此我们在进行复制前,可以先运行看看,看query表把什么东西提取出来了(因此外连接、内连接全都支持)。
6.更新单行
把invoices表中的第一条(invoice_id = 1)数据更新,代码如下
USE sql_invoicing;
UPDATE invoices
SET payment_total = 10,payment_date = '2019-03-01'
WHERE invoice_id = 1
更新时,set的内容也没有任何限制(就和select一样)
7.更新多行
现在需要把 client_id = 3 的信息全部都修改掉。
在某些版本的mysql引擎中一个where条件修改多条语句会报错,解决方法如下:
在mysqlworkbench中找到preferences,然后出现窗口以后点击sql editor,划到最后取消safe updates 勾选。
8.在updates中使用子查询
UPDATE invoices
SET payment_total = 10
WHERE client_id =
(SELECT client_id
FROM clients
WHERE name = 'Myworks')
子查询相当于在select中套了一层select。
技巧:可以先把一层select写出来并运行看看,然后再在外面套一层select。
9.删除行
DELETE FROM invoices
WHERE invoice_id = 1
上面的代码就是delete的基本格式,如果没有where,那就会把一整张表的数据全都删除。
10.恢复数据库
在file菜单中选择open SQL script,然后选择同一文件并点击确认,然后点击闪电图标……(同原来的操作)。这相当于把整个数据库的表格全都重置了一遍。