DOS命令行
登录格式1:登录本机的MySQL
- mysql -u用户名 -p密码
-
登录格式2:登录远程的MySQL
mysql -u用户名 -p密码 –h远程主机ip
示例:mysql -uroot -proot -h127.0.0.1
退出MySQL
-
MySQL相关概念
数据库、表、数据的关系
MySQL服务器中可以创建多个数据库
- 每个数据库中可以包含多张表
- 每个表中可以存储多条数据记录
-
关系型数据库介绍
关系型数据库是建立在关系模型基础上的数据库,简单说,关系型数据库是由多张能互相连接的二维表组成的数据库
SQL的介绍
SQL(Structured Query Language):结构化查询语言,一门操作关系型数据库的编程语言
通用语法规则
SQL 语句可以单行或多行书写,以分号结尾
- MySQL 数据库的 SQL 语句不区分大小写,关键字建议使用大写
- 单行注释:— 注释内容 #注释内容(MySQL特有)
-
SQL语言分类
1.DDL : Data Definition Language(数据定义语言)
用来定义数据库对象:数据表,表,列等;包括了:create(添加),alter(修改),drop(删除),truncate(这是删除并新建表,可消除自增的历史最大值);
2.DML : Data Manipulation Language(数据操作语言)
用来对数据库表的数据进行增删改,包括了:insert(插入),delete(删除),update(更新);
3.DQL : Data Query Language(数据查询语言)
用来查询数据库中表的记录(数据),包括了select(数据库的重点,重点中的重点),where;
4.DCL : Data Control Language(数据控制语言)
用来定义数据库的访问权限和安全级别,包括分配数据库用户权限相关的sql语句,grant,revoke; :::
DDL:操作数据库、表
操作数据库
C(create):创建
创建数据库:
- create database 数据库名称;
- 创建数据库,判断不存在,再创建:
- create database if not exists 数据库名称;
- 创建数据库,并指定字符集
- create database 数据库名称 character set 字符集名;
练习:创建db4数据库,判断是否存在,并指定字符集为gbk
查询所有数据库名称:
- show databases;
查询某个数据库的字符集:查询某个数据库的创建语句;
修改数据库的字符集:
删除数据库:
- drop database 数据库名称;
判断数据库是否存在,存在再删除
查询当前正在使用数据库的名称
- select database();
- 使用数据库
- use 数据库名称 ::: ```sql / DDL操作数据库 / — 查看所有数据库 SHOW DATABASES;
— 直接创建数据库db1 CREATE DATABASE db1;
— 判断是否存在并创建数据库db2 CREATE DATABASE IF NOT EXISTS db2;
— 删除db2数据库 DROP DATABASE db2;
— 判断数据库存在才删除 DROP DATABASE IF EXISTS db2;
— 使用数据库 USE db1;
:::tips
<a name="RoVPD"></a>
### 操作表
<a name="xoeB5"></a>
#### C(create):创建
- 语法:
1. create table 表名(
1. 列名1 数据类型1,
1. 列名2 数据类型2,
1. ...
1. );
<a name="b7Pla"></a>
##### [注意:最后一列不需要加(,)]
<a name="J5XLX"></a>
#### 数据库类型;
- int : 整数类型age int
- double : 小数类型score double( , )
- date: 日期,只包含年月日,yyyy-MM-dd
- datetime : 日期,包含年月日时分秒 yyyy-MM-dd HH:mm:ss
- timestamp : 时间错类型 包含年月日时分秒 yyyy-MM-dd HH:mm:ss
[如果将来不给这个字段赋值,或赋值为null,则默认使用当前系统时间,来自动赋值]
- varchar() : 字符串,可变长度,使用几个字符就占几个
- char(): 字符串,固定长度的字符串,无论传多少个字符都占满
<a name="c9YD2"></a>
#### 复制表:
- create table 表名 like 被复制的表名
<a name="fHXPq"></a>
#### R(retrieve):查询
- 查询某个数据库所有表名称:
- show tables;
- 查询表结构:
- desc 表名;
<a name="sNukC"></a>
#### U(update):修改
- 修改表名:
- alter table 表名 rename to 新的表名;
- 修改表的字符集:
- alter table 表名 character set 字符集名称;
- 添加一列:
- alter table 表名 add 列名 数据类型;
- 修改数据类型:
- alter table 表名 modify 列名 新数据类型;
- 修改列名:
- alter table 表名 change 列名 新列名 数据类型;
<a name="AG7qT"></a>
#### D(delete):删除
- drop table 表名;
- drop table if exists 表名;
- 删除列
- alter table 表名 drop 列名
:::
```sql
/* DDL操作表 */
/*
创建商品表(goods)包含:
商品名称(name),
商品价格(price),
商品销量(sales_volume),
商品生产日期(produced_date)
*/
CREATE TABLE goods(
NAME VARCHAR(10),
price DOUBLE,
sales_volume INT,
produced_date DATE
);
/*
需求:设计一张学生表,请注重数据类型、长度的合理性
编号, 整数
姓名, 姓名最长不超过10个汉字
性别, 因为取值只有两种可能(男或女),因此用一个汉字
生日, 取值为年月日
入学成绩, 小数点后保留两位
邮件地址, 最大长度不超过 64
家庭联系电话, 不一定是手机号码,可能会出现 - 等字符,20位以内
*/
CREATE TABLE students(
id INT,
NAME VARCHAR(10),
sex CHAR(1),
birthday DATE,
score DOUBLE(5, 2), -- 总五位,小数占两位 : 100.00
e_mail VARCHAR(64),
phone_num VARCHAR(20)
);
-- 查看db1数据库中的所有表
SHOW TABLES;
-- 查看表结构
DESC goods;
-- 删除表goods表
DROP TABLE goods;
-- 将goods改名成goods2
ALTER TABLE goods RENAME TO goods2;
-- 为goods2表添加一个新的字段img,类型为varchar(20)
ALTER TABLE goods2 ADD img VARCHAR(20);
-- 将goods2表中的img字段的改成varchar(100)
-- 将goods2表中的img字段名改成icon,类型varchar(80)
ALTER TABLE goods2 CHANGE img icon VARCHAR(80);
-- 删除goods2表中的字段icon
ALTER TABLE goods2 DROP icon;
DML 增删改表中数据
添加数据:
语法:
语法:
语法:
- update 表名 set 列名1 = 值1,列名2 = 值2,…[where条件]; ::: ```sql / DML操作表中记录 / — 插入数据, 给指定列添加数据 给goods表添加一条数据 NAME=’格力空调’, price=3699 — 注意:在MySQL中字符串可以使用””或’’, 建议’’ INSERT INTO goods (NAME, price) VALUE (‘格力空调’, 3999);
— 插入数据, 所有的字段名都写出来(少数做法) — NAME=’华为P40’, price=5999, sales_volume=1000, produced_date=’2020-08-20’ — 注意:日期使用’’ INSERT INTO goods (NAME, price, sales_volume, produced_date) VALUE (‘华为P40’, price=5999, sales_volume=1000, produced_date=’2020-08-20’);
— 插入数据, 插入所有字段不写字段名(常用做法) — ‘小米11’, 4999, 300, ‘2021-03-22’ INSERT INTO goods VALUE (‘小米11’, 4999, 300, ‘2021-03-22’);
— 扩展:一条SQL语句加入多条数据, VALUES 后面可以跟多个(), 一个()对应一条数据 — ‘iPhone 12’, 6799, 12000, ‘2020-10-28’ — ‘DELL 7590’, 8799, 300, ‘2019-06-18’ — ‘立白洗衣粉’, 12.9, 39000, ‘2018-02-13’
INSERT INTO goods VALUE (‘iPhone 12’, 6799, 12000, ‘2020-10-28’), (‘DELL 7590’, 8799, 300, ‘2019-06-18’), (‘立白洗衣粉’, 12.9, 39000, ‘2018-02-13’);
— 不带条件修改数据,将所有的price改成0 UPDATE goods SET price = 0;
— 带条件修改数据,把name为’华为P40’的商品price改成5999 UPDATE goods SET price = 5999 WHERE NAME = ‘华为P40’;
— 一次修改多个列,把name为’小米11’的商品price改成3999, sales_volume改成10000 UPDATE goods SET price = 3999, sales_volume = 1000 WHERE NAME = ‘小米11’;
— 带条件删除数据,删除name为’小米11’的数据 DELETE FROM goods WHERE NAME = ‘小米11’;
— 不带条件删除数据,删除表中的所有数据 DELETE FROM goods;
<a name="tEoSu"></a>
### DQL查询表中的记录
:::tips
<a name="rwQiB"></a>
#### select * from 表名
- 语法:
- select 字段列表
- from 表名列表
- where 条件列表
- group up 分组字段
- having 分组之后的条件
- order by 排序
- limit 分页限定
<a name="F9APe"></a>
#### 基础查询
- 多个字段的查询:
- select 字段名1,字段名2...from 表名;
- 去除重复:
- select distinct 字段名 from 表名;
<a name="GQa61"></a>
#### 条件查询
- where子句后跟条件
- 运算符
- ' > ' ' < ' ' >= ' ' <= ' ' = ' ' <> '
- between...and 某个范围内(包含)
- in 多选一
- like 模糊查询
- 占位符:
- _ 单个任意字符
- % 多个任意字符
- is null 为空
- is not null 不为空
- and 或 && 并且
- or 或 || 或者
- not 或 ! 非,不是
- and和or同时出现,and优先级较高。如果想让or先执行,需要加“小括号”
:::
:::tips
<a name="ybwmq"></a>
#### 案例:
- 查询年龄大于20岁
- select * from 表名 where age > 20;
- select * from 表名 where age >= 20;
- 查询年龄等于20岁
- select * from 表名 where age = 20;
- 查询年龄不等于20岁
- select * from 表名 where age != 20;
- select * from 表名 where age <> 20;
- 查询年龄大于等于20岁,小于等于30
- select * from 表名 where age >= 20 && <= 30;
- select * from 表名 where age >= 20 and <= 30;
- select * from 表名 where age between 20 and 30;
- 查询年龄20岁,30岁 40岁
- select * from 表名 where age = 20 or age = 30 or age = 40;
- select * from 表名 where age in (20,30,40);
- 查询成绩为null
- select * from 表名 where gra is null; 【注意】不能使用[gra = null]这种写法
- 查询成绩不为null
- select * from 表名 where gra is not null;
:::
<a name="jSpcN"></a>
### DQL查询语句
:::tips
<a name="H6EYO"></a>
#### 排序查询:
- 语法:order by子句
- order by 排序字段1,排序方式1,排序字段2,排序方式2...
- 排序方式:
- ASC:升序;
- DESC:降序;
- [注意:如果有多个排序条件,则前面条件值一样时,才会判断第二条件]
- 案例:
- select * from 表名 order by 列名1 ASC/DESC, 列名2 ASC/DESC;
<a name="z3veM"></a>
#### 聚合函数:将一列数据作为一个整体,进行纵向的计算
- count: 计算个数
- max: 计算最大值
- min: 计算最小值
- sum: 计算和
- avg: 计算平均值
- [注意:聚合函数的计算是排除null的]
- 如果想要将null值计算入内,需把null换为0
- select count (ifnull(列名, 0)) from 表名;
<a name="WSXWK"></a>
##### 案例:
- select max(列名) from 表名;
<a name="Rl701"></a>
#### 分组查询:
<a name="gmrkR"></a>
#### 语法:group by 分组字段;
- [注意:分组之后查询的字段:分组字段,聚合函数]
- select 分组列, avg(列名1), count(列名2) from 表名 group by 分组列;
<a name="oHuN6"></a>
##### 案例:
- 按照性别(sex)分组,分别查询出男女同学的平均分(math),人数(id)。
- 要求:分数低于70的人不参与分组,分组之后,人数要大于2人
- {
- select sex, avg(math),count(id) from 表名 where math > 70 group by sex having count(id) > 2;
- }
<a name="f1Fmu"></a>
##### [注意:]
<a name="RQj0f"></a>
###### where 与 having 的区别:
- where 在分组之前进行限定,如果不满足,则不参与分组。
- having 在分组之后进行限定,如果不满足结果,则不会查询出来。
- where 后不可跟聚合函数。
- having 可以进行聚合函数的判断。
<a name="LDhPm"></a>
#### 分页查询:
<a name="D9CMk"></a>
##### 语法:limit 开始的索引, 每页查询的条数;
<a name="Ywdkl"></a>
###### 案例:每页显示3条记录
- {
- select * from 表名 limit 0, 3; --第一页
- select * from 表名 limit 3, 3; --第二页
- select * from 表名 limit 6, 3; --第三页
- }
<a name="Y33kr"></a>
###### [公式:开始的索引 = (当前的页码 - 1) * 每页显示的条数]
<a name="GR1Qe"></a>
#### Select 语句执行顺序
from 执行笛卡尔积<br />on 筛选<br />join 连接<br />where 过滤条件<br />group by 分组操作<br />avg()/sum() 聚合函数<br />having 过滤器<br />select 选择<br />order by 排序操作<br />asc/desc 升序降序<br />limit 分页
:::
```sql
/* DQL查询记录 */
-- 准备数据
CREATE TABLE goods2 (
NAME VARCHAR(10),
price DOUBLE,
sales_volume INT,
produced_date DATE,
category VARCHAR(20)
);
INSERT INTO goods2 VALUES
('华为P40',5999,1000,'2020-08-20','手机'),
('小米11',4999,5000,'2020-12-28','手机'),
('红米K30',2999,22000,'2020-03-11','手机'),
('糯米',8.99,200,'2016-06-08','食物'),
('米糊',7.99,30,'2013-11-22','食物'),
('iPhone 12',6799,12000,'2020-10-28','手机'),
('DELL 7590',8799,300,'2019-06-18','电脑'),
('立白洗衣粉',12.9,39000,'2018-02-13','日用品'),
('立白洗衣粉',12.9,39000,'2018-02-13','日用品'),
(NULL,88,666,NULL,NULL),
('联想电脑',8799,700,'2017-03-13','电脑'),
('惠普电脑',8799,50,'2008-12-13','电脑');
-- 查询goods2表中的 name 和 price 列
SELECT NAME, price FROM goods2;
-- 细节:查询只是查看数据,不会修改表中数据
-- 查询goods2表中所有字段
SELECT * FROM goods2;
-- 查询所有字段, 使用*代表所有列, 列就是字段
-- 我们学习是一般使用*这样查询简单快速,实际工作中,你需要什么字段就查询什么字段.
-- 去除重复查询: DISTINCT
SELECT DISTINCT NAME FROM goods2;
-- 查询goods2表中的 name 和 price 列
-- name列的别名为 商品名称,price列的别名为 价格
SELECT NAME AS 名称, price AS 价格 FROM goods2;
-- 取别名时AS关键字可以省略
SELECT NAME 名称, price 价格 FROM goods2;
-- 条件查询
-- 查询price大于1000的商品
SELECT * FROM goods2 WHERE price > 1000;
-- 查询sales_volume小于5000的商品
SELECT * FROM goods2 WHERE price < 5000;
-- 查询price不等于6799的商品
SELECT * FROM goods2 WHERE price != 6799;
SELECT * FROM goods2 WHERE price != 6799;
-- 逻辑运算符
-- 查询price大于1000且sales_volume小于500的商品(两个条件同时满足)
SELECT * FROM goods2 WHERE price > 1000 AND sales_volume < 500;
-- 查询price大于8000 或 sales_volume小于100的商品(两个条件其中一个满足)
SELECT * FROM goods2 WHERE price > 8000 OR sales_volume < 100;
-- 查询name是华为P40和小米11和米糊的商品
SELECT * FROM goods2 WHERE NAME = '华为P40' OR NAME = '小米11' OR NAME = '米糊';
-- in: 在...里面,只要是满足()里面的数据都可以
-- 查询name是 华为P40 和 小米11 和 米糊 的商品
SELECT * FROM goods2 WHERE NAME IN('华为P40', '小米11', '米糊');
-- 扩展:查询name不是华为P40和小米11和米糊的商品
SELECT * FROM goods2 WHERE NAME NOT IN('华为P40', '小米11', '米糊');
-- 范围: BETWEEN 值1 AND 值2 -- 表示从值1到值2范围,包头又包尾
-- 查询price大于等于1000,且小于等于5000的商品
SELECT * FROM goods2 WHERE price BETWEEN 1000 AND 5000;
-- 细节: between 值1 and 值2, 小的写前,面大的写后面
-- 扩展:查询商品名称是null的商品
SELECT * FROM goods2 WHERE NAME IS NULL;
-- 扩展:查询商品名称不是null的商品
SELECT * FROM goods2 WHERE NAME IS NOT NULL;
-- 模糊查询like
-- 查询米开头的商品
SELECT * FROM goods2 WHERE NAME LIKE '米%';
-- 查询商品名称中包含'米'字的商品
SELECT * FROM goods2 WHERE NAME LIKE '%米%';
-- 扩展:查询名称第二个字为米的商品
SELECT * FROM goods2 WHERE NAME LIKE '_米%';
-- 扩展:查询名称最后字为米的商品
SELECT * FROM goods2 WHERE NAME LIKE '%米';
/* 查询排序 */
-- order by 表示排序, ASC升序, DESC降序
-- 单列排序
-- 查询所有数据,使用price升序排序
SELECT * FROM goods2 ORDER BY price;
SELECT * FROM goods2 ORDER BY price ASC;
-- 查询所有数据,使用price降序排序
SELECT * FROM goods2 ORDER BY price DESC;
-- order by 默认是升序
-- 组合排序
-- 查询所有数据,在price降序排序的基础上,如果price相同再以sales_volume降序排序
SELECT * FROM goods2 ORDER BY price DESC, sales_volume DESC;
-- 聚合函数
-- SELECT 聚合函数(字段) FROM 表名;
-- 查询商品个数, COUNT统计时会忽略NULL值
SELECT COUNT(NAME) FROM goods2;
-- COUNT最好的处理方式, *表示所有列理解为统计行数,最准确
SELECT COUNT(*) FROM goods2;
-- 扩展用法:统计price大于1000的总个数
SELECT COUNT(*) FROM goods2 WHERE price > 1000;
-- 查询所有商品总销量
-- 总销量是把所有商品的销量加起来
SELECT SUM(sales_volume) FROM goods2;
-- 查询销量最低的商品
SELECT MIN(sales_volume) FROM goods2;
-- 查询销量最高的商品
SELECT MAX(sales_volume) FROM goods2;
-- 查询商品平均价格
SELECT AVG(price) FROM goods2;
-- 扩展:让小数显示指定的位数(2位)
-- ROUND(数据, 小数位数)
SELECT ROUND(AVG(price), 2) FROM goods2;
-- 细节:如果不是数值类型(整数/小数),那么聚合函数计算结果为0。
/* 分组查询 */
-- 按商品类型分组
SELECT * FROM goods2 GROUP BY category;
-- 分组后会返回每组的第一条数据
-- 通常我们只获取分组字段
SELECT category FROM goods2 GROUP BY category;
-- 分组后通常是为了统计,分组后聚合函数操作每一组的数据
-- 查询每种类型的商品数量
SELECT category, COUNT(*) FROM goods2 GROUP BY category;
-- 查询销量大于100的商品,按商品类型分组,统计每组的数量
SELECT category, COUNT(*) FROM goods2 WHERE sales_volume > 100 GROUP BY category;
-- 查询销量大于100的商品,按商品类型分组,统计每组的数量,并只显商品类型数量大于2的数据
SELECT category, COUNT(*) FROM goods2 WHERE sales_volume > 100 GROUP BY category HAVING COUNT(*) > 2;
/* 分页查询 */
-- 查询商品表中数据,跳过前面2条,显示3条
SELECT * FROM goods2 LIMIT 2, 3;
-- 假设我们一每页显示3条记录的方式来分页,SQL语句如下:
-- 第一页: 跳过0条, 获取3条
SELECT * FROM goods2 LIMIT 0, 3;
-- 如果跳过的条数是0,可以省略
SELECT * FROM goods2 LIMIT 3;
-- 第二页: 跳过3条, 获取3条
SELECT * FROM goods2 LIMIT 3, 3;
-- 第三页: 跳过6条, 获取3条
SELECT * FROM goods2 LIMIT 6, 3;
-- 第四页: 跳过9条, 获取3条
SELECT * FROM goods2 LIMIT 9, 3;
/*扩展查询的七个关键字顺序
SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY
LIMIT
*/
-- 先查询表里面所有的数据并进行过滤。(此时用where关键字过滤的是表里面的数据,把name为null的给过滤掉了)
-- 然后进行分组,并统计每一组有多少条数据。
-- 利用HAVING关键字对查询的结果再次过滤 把个数大于等于2的展示出来。
-- 对having过滤之后的结果按照个数进行排序
-- 最后再跳过第一个,展示两条数据
SELECT category, COUNT(*) AS 个数 FROM goods WHERE NAME IS NOT NULL GROUP BY category HAVING 个数 >= 2 ORDER BY 个数 ASC LIMIT 1,2;