mysql基础学习笔记

1. 数据库相关概念

DBdatabase,即存储数据的仓库,它保存了一系列由组织的数据

DBMSdatabase management system,数据库管理系统,数据库是通过数据库管理系统创建和操作的容器

SQLstructure query language,结构化查询语言,用来与数据库通信的语言

2. MySQL数据库的使用

2.1 windows系统通过命令行启动mysql服务

以管理员身份打开命令行后,通过net start xxxnet stop xxx启动和停止mysql服务,其中xxx表示mysql的服务名

2.2 通过命令行登录mysql客户端

  1. 在命令行输入mysql -uxxx -pzzz即可登录服务,其中xxx表示用户名,zzz表示密码,这种方式密码可见
  2. 在命令行输入mysql -uxxx -p,回车后再输入密码,这种方式密码不可见

3. SQL分类

  1. DDL:data definition language,数据定义语言,用来定义数据库对象,比如库、表和列等,用到关键词createdropalter
  2. DML:data manipulation language,数据库操作语言,用于定义数据库记录(数据),用到关键词insertupdatedelete
  3. DCL:data control language,数据控制语言,用来定义访问权限和安全级别
  4. DQL:data query language,数据查询语言,用来查询记录(数据),用到关键词select

4. DQL

4.0 执行顺序

sql语句内各关键字执行是按照一定顺序进行的,具体为:

fromjoinonwheregroup byhavingselectorder bylimit

4.1 基础查询

# 1. 查询常量
SELECT 100;

# 2. 查询表达式
SELECT 100 * 3;

# 3. 查询单个字段
SELECT last_name FROM employees;

# 4. 查询多个字段
SELECT last_name, email, employee_id FROM employees;

# 5. 查询所有字段
SELECT * FROM employees;

# 6. 查询函数(调用函数,获取返回值)
SELECT DATABASE();
SELECT VERSION();
SELECT USER();

# 7. 别名
# 方式一:使用as关键字
SELECT USER() AS 用户名;
SELECT last_name AS '姓 名' FROM employees;
# 方式二:使用空格
SELECT USER() 用户名;
SELECT last_name '姓 名' FROM employees;

# 8. mysql中+的应用
# (1). 操作数是数值类型,直接相加
SELECT 1 + 1;
# (2). 操作数是字符类型,若能转成为数值类型,则转换后继续运算
#    若不能转换为数值类型,则变为0
SELECT 1 + '2';
SELECT 1 + 'zz';
# (3). 若其中一个操作数为null,那么结果必定为null
SELECT NULL + 1;
SELECT NULL + 'zz';

# 9. 字符类型拼接
SELECT CONCAT(first_name, last_name) AS 姓名 FROM employees;

# 10. distinct关键字,去重
SELECT DISTINCT department_id FROM employees;

# 11. 查看表结构
DESC employees;
SHOW COLUMNS FROM employees;

4.2 条件查询

# 1. 按关系表达式筛选
# 关系运算符:>,<,>=,<=,=,<>,!=(不推荐)

# 查询部门编号不是100的员工信息
SELECT * FROM employees WHERE department_id <> 100;

# 查询工资小于15000的姓名、工资
SELECT last_name, salary FROM employees WHERE salary < 15000;

# 2. 按逻辑表达式筛选
# 逻辑运算符:and、or和not,也可以支持&&、||、!

# 查询部门编号不是50-100之间的员工姓名、部门编号和邮箱
SELECT last_name, department_id, email FROM employees WHERE department_id <= 50 OR department_id >= 100;
SELECT last_name, department_id, email FROM employees WHERE NOT(department_id > 50 AND department_id < 100);

# 查询奖金率大于0.03或者员工编号在60到100之间的员工信息
SELECT * FROM employees WHERE commission_pct > 0.03 OR (employee_id > 60 AND employee_id < 100);

# 3. 模糊查询
# like、in、between and、is null

# (一). like,通常和通配符搭配使用
# 常见的通配符有:
# 	(1). _:表示任意单个字符
#	(2). %:表示任意多个字符

# 查询员工姓名中包含字符a的员工信息
SELECT * FROM employees WHERE last_name LIKE '%a%';

# 查询姓名中第三个字符为x的员工信息
SELECT * FROM employees WHERE last_name LIKE '__x%';

# 查询姓名中第二个字符为_的员工信息
SELECT * FROM employees WHERE last_name LIKE '_\_%';
SELECT * FROM employees WHERE last_name LIKE '_$_%' ESCAPE '$';

# (二). in/not in,用于查询某个字段是否属于指定的列表

# 查询部门编号是30、50或90的员工信息
SELECT * FROM employees WHERE department_id IN(30, 50, 90);

# 查询工种编号不是SH_CLERK和IT_PROG的员工信息
SELECT * FROM employees WHERE job_id NOT IN('SH_CLERK', 'IT_PROG');

# (三). between and,判断某个字段是否介于该区间
# 查询部门编号在30-90之间的员工信息
SELECT * FROM employees WHERE department_id BETWEEN 30 AND 90;

# (四). is null/is not null
# 查询没有奖金的员工信息
SELECT * FROM employees WHERE commission_pct IS NULL;

4.3 排序查询

# 排序查询

# order by
# 排序列表可以是单个字段、多个字段、表达式、函数、列数以及以上组合
# asc:升序,默认行为
# desc,降序

# 1. 按单个字段排序
# 将员工编号大于120的员工信息按照工资升序
SELECT * FROM employees WHERE employee_id > 120 ORDER BY salary;

# 2. 按表达式排序
# 对有奖金的员工姓名和年薪按照年薪降序排列
SELECT last_name, salary * 12 * (1 + IFNULL(commission_pct, 0)) AS 年薪 
FROM employees WHERE commission_pct IS NOT NULL ORDER BY 年薪 DESC;

# 3. 按函数结果排序
# 按姓名的长度进行升序排序
SELECT last_name FROM employees ORDER BY LENGTH(last_name);

# 4. 按多个字段排序
# 查询员工姓名、工资、部门编号,先按照工资升序,再按照部门编号降序
SELECT last_name, salary, department_id FROM employees ORDER BY salary ASC, department_id DESC;

# 5. 按列数排序
# 查询员工信息,并以第二列升序显示
select * from employees order by  2;

4.4 函数

4.4.1 字符函数

# 1. concat 拼接字符
SELECT CONCAT('hello', first_name, last_name) 备注 FROM employees;

# 2. length 获取字符串的字节长度,使用utf8时,一个汉字占3个字节
# 输出8
SELECT LENGTH('12345李') AS 'length';

# 3. char_length 获取字符长度
# 输出6
SELECT CHAR_LENGTH('12345李');

# 4. substr 截取子串
# substr(str, 起始索引-1开始,截取字符串的长度)
# substr(str, 起始索引),截取从某个位置开始到结尾的所有
SELECT SUBSTR('1爱上了2', 2, 3);
SELECT SUBSTR('1爱上了2', 2);

# 5. instr 获取字符第一次出现的索引
SELECT INSTR('三打白骨精', '白骨精');

# 6. trim 去掉前后指定字符,默认去掉空格
SELECT LENGTH(TRIM('  天龙八部   '));
SELECT TRIM('x' FROM 'xxxxxxx天空xx八部xxx');

# 7. lpad, rpad 左填充,右填充
SELECT LPAD('天龙八部', 10, 'a');

# 8. upper, lower 变大写,变小写
SELECT UPPER('lilili');

# 9. strcmp 比较字符大小
SELECT STRCMP('aaa', 'abc');

# 10. left, right 从左、右截取子串
SELECT LEFT('天龙八部', 1);

4.4.2 数学函数

# 1. abs 绝对值
SELECT ABS(-19);

# 2. ceil 向上取整
SELECT CEIL(-0.1);
SELECT CEIL(9.99);

# 3. floor 向下取整
SELECT FLOOR(-0.1);

# 4. round 四舍五入
SELECT ROUND(-0.5);

# 5. truncate 截取小数点后几位
SELECT TRUNCATE(1.23456, 20);

# 6. mod 取余
SELECT MOD(-10, 3);

4.4.3 日期函数

# 1. now, 输出:2020-02-25 16:27:20
SELECT NOW();

# 2. curdate, 输出:2020-02-25
SELECT CURDATE();

# 3. curtime, 输出:16:29:34
SELECT CURTIME();

# 4. datediff
SELECT DATEDIFF(NOW(), '1990-10-10');

# 5. date_formate, 格式化
SELECT DATE_FORMAT(NOW(), '%Y年%m月%d日 %H时%i分%s秒');

4.4.4 流程控制函数

# 1. if
SELECT IF(10 > 9, 1, 2);

# 2. case
# (1) case exp
#     when v1 then result1
#     when v2 then result2
#     when v3 then result3
#     else result4
#     end
# 部门编号为30,工资显示为3倍,编号为40,工资显示为4倍,否者正常显示工资
SELECT department_id, last_name, 
CASE department_id 
WHEN 30 THEN salary * 3
WHEN 40 THEN salary * 4
ELSE salary
END AS '新工资'
FROM employees;

# (2) 类似于多重if语句,实现区间判断
#     case 
#     when exp1 then result1
#     when exp2 then result2
#     when exp3 then result3
#     else result4
#     end
# 如果工资大于20000, 显示级别为A
# 如果工资大于15000, 显示级别为B
# 否则显示C
SELECT salary, 
CASE 
WHEN salary > 20000 THEN 'A'
WHEN salary > 15000 THEN 'B'
ELSE 'D'
END '级别'
FROM employees;

4.4.5 分组函数

分组函数常用于实现将一组数据进行统计计算,最终得到一个值,又称为聚合函数或统计函数

# 1. sum 求某个字段所有值的和
# 2. avg 求某个字段的平均值
# 3. max、min 求某个字段的最大值、最小值
# 4. count 计算非空字段个数
SELECT SUM(salary), AVG(salary), MIN(salary), MAX(salary), COUNT(salary) FROM employees;

4.5 分组查询

# 1. 查询每个工种的员工平均工资
SELECT job_id, AVG(salary) FROM employees GROUP BY job_id;

# 2. 每个领导的手下的人数
SELECT manager_id, COUNT(*) FROM employees WHERE manager_id IS NOT NULL GROUP BY manager_id;

# 3. 查询每个部门中员工的邮箱中包含a字符的员工最高工资
SELECT department_id, MAX(salary) FROM employees 
WHERE email LIKE '%a%' AND department_id IS NOT NULL GROUP BY department_id;

# 4. 查询每个领导手下有奖金的员工的平均工资
SELECT manager_id, AVG(salary) FROM employees WHERE commission_pct IS NOT NULL GROUP BY manager_id;

# 5. 查询哪个部门的员工个数大于5
# 这道题的筛选条件为部门的员工个数大于5,也就是说要先按照部门分组,然后再筛选,
# 因此筛选条件的关键字是不能用where的,因为where关键字的执行顺序实在group by之
# 前的,因此就需要having关键字,负责分组后的条件筛选。
SELECT department_id, COUNT(employee_id) FROM employees WHERE employee_id IS NOT NULL 
GROUP BY department_id HAVING COUNT(employee_id) > 5;

# 6. 每个工种有奖金的员工的最高工资大于12000的工种编号和最高工资
SELECT job_id, MAX(salary) FROM employees WHERE commission_pct IS NOT NULL 
GROUP BY job_id HAVING MAX(salary) > 12000;

# 7. 领导编号大于102的每个领导手下的最低工资大于5000的领导编号和最低工资
SELECT manager_id, MIN(salary) FROM employees WHERE manager_id > 102 
GROUP BY manager_id HAVING MIN(salary) > 5000;

# 8. 查询没有有奖金的员工的最高工资大于6000的工种编号和最高工资,按照最高工资升序
SELECT job_id, MAX(salary) FROM employees WHERE commission_pct IS NULL 
GROUP BY job_id HAVING MAX(salary) > 6000 ORDER BY MAX(salary);

# 9. 查询每个工种、每个部门的最低工资,并按照最低工资降序
SELECT job_id, department_id, MIN(salary) FROM employees 
GROUP BY job_id, department_id ORDER BY MIN(salary) DESC;

4.6 连接查询

4.6.0 概览

在这里插入图片描述

4.6.1 连接查询的分类

  1. 按功能

    1. 内连接

      扫描二维码关注公众号,回复: 10045971 查看本文章
      1. 等值连接

      2. 非等值连接

      3. 自连接

    2. 外连接

      1. 左外连接

      2. 右外连接

      3. 全外连接

    3. 全连接

  2. 按年代

    1. sql92:仅支持内连接

    2. sql99(推荐):支持内连接、外连接(左外、右外)和交叉连接

4.6.2 sql92

4.6.2.1 内连接

################等值连接################

# 1. 查询员工名和部门名
SELECT last_name, department_name FROM employees emp, departments dep 
WHERE emp.department_id = dep.department_id;

# 2. 查询部门编号大于100的部门名和所在的城市名
SELECT dep.department_name, loc.city FROM departments dep, locations loc 
WHERE dep.location_id = loc.location_id AND dep.department_id > 100;

# 3. 查询有奖金的员工名和部门名
SELECT emp.last_name, dep.department_name FROM departments dep, employees emp 
WHERE emp.commission_pct IS NOT NULL AND emp.department_id = dep.department_id;

# 4. 查询城市名中第二个字符为'o'的部门名和城市名
SELECT dep.department_name, loc.city FROM locations loc, departments dep
WHERE dep.location_id = loc.location_id AND loc.city LIKE '_o%';

# 5. 查询每个城市的部门个数
SELECT loc.city, COUNT(dep.department_id) FROM locations loc, departments dep
WHERE dep.location_id = loc.location_id GROUP BY loc.city;

# 6. 查询哪个部门的员工个数大于5,并按员工个数降序
SELECT dep.department_name, COUNT(emp.employee_id) 
FROM employees emp, departments dep
WHERE emp.department_id = dep.department_id 
GROUP BY emp.department_id 
HAVING COUNT(emp.employee_id) > 5 
ORDER BY COUNT(emp.employee_id) DESC;

4.6.3 sql99

4.6.3.1 内连接

内连接语法,新增了join关键字,并通过on关键字实现连接条件和筛选条件的分离

# []表示可选
select cols from table1 [inner] join table2 on join_condition where conditions
group by group_cols having group_conditions order by cols;
################等值连接################

# 1. 查询员工名和部门名
SELECT emp.last_name, dep.department_name  FROM employees emp JOIN departments dep 
ON emp.department_id = dep.department_id;

# 2. 查询部门编号大于100的部门名和所在的城市名
SELECT dep.department_name,loc.city FROM locations loc JOIN departments dep 
ON dep.location_id = loc.location_id WHERE dep.department_id > 100;

# 3. 查询每个城市的部门个数
SELECT loc.city, COUNT(dep.department_id) FROM locations loc JOIN departments dep 
ON dep.location_id = loc.location_id GROUP BY loc.city;

# 4. 查询部门中员工个数大于10的部门名,并按部门名降序
SELECT dep.department_name, COUNT(emp.employee_id) FROM employees emp JOIN departments dep 
ON emp.department_id = dep.department_id GROUP BY dep.department_id HAVING COUNT(emp.employee_id) > 10
ORDER BY dep.department_name DESC;

################非等值连接################


################自连接################

# 1. 查询员工名和对应的领导名
SELECT e.last_name 员工名, l.last_name 领导名 
FROM employees e JOIN employees l ON e.manager_id = l.employee_id;

4.6.3.2 外连接

查询结果为主表中的所有记录,如果从表中有匹配项,则显示匹配项;如果从表中没有匹配项,则显示null。
外连接查询一般用来查询主表中有但从表中没有的记录项,基本语法为:

  1. 外连接分主表和从表,且两表的顺序不能随意调换
  2. 左连接左表是主表
  3. 右连接右表是主表
# 1. 查询编号大于3的女孩的男朋友信息,有则列出,无则用null填充
SELECT beauty.*, boys.boyName FROM beauty LEFT JOIN boys 
ON beauty.boyfriend_id = boys.id WHERE beauty.id > 3;

# 2. 查询哪个城市没有部门
SELECT loc.city FROM locations loc LEFT JOIN departments dep ON loc.location_id = dep.location_id
WHERE dep.department_id IS NULL;

# 3. 查询部门名为SAL或IT的员工信息
SELECT emp.last_name FROM employees emp JOIN departments dep ON emp.department_id = dep.department_id 
WHERE dep.department_name = 'SAL' OR dep.department_name = 'IT';

4.7 子查询

# 1. 查询和Zlotkey相同部门的员工名和工资
SELECT emp.last_name, emp.salary FROM employees emp WHERE emp.department_id = 
(SELECT emp.department_id FROM employees emp WHERE emp.last_name = 'Zlotkey');

# 2. 查询工资比公司平均工资高的员工的员工号、姓名和工资
SELECT emp.employee_id, emp.last_name, emp.salary FROM employees emp
WHERE emp.salary > (SELECT AVG(salary) FROM employees WHERE salary IS NOT NULL);

# 3. 查看location_id是1400或1700的部门中所有员工姓名
SELECT last_name FROM employees WHERE department_id IN 
(SELECT department_id FROM departments WHERE location_id IN (1400, 1700));

# 4. 返回其它部门中比job_id为'IT_PROG'的部门的任一员工工资低的员工工号、姓名、job_id和工资
SELECT employee_id, last_name, job_id, salary FROM employees 
WHERE salary < (SELECT MAX(salary) FROM employees WHERE job_id = 'IT_PROG') 
AND job_id != 'IT_PROG';

4.8 分页查询

limit关键字,后面接两个参数,分别是起始条目数和显示条目数,注意起始从0开始,且默认为0

# 1. 员工信息表的前5条
SELECT * FROM employees LIMIT 5;   
SELECT * FROM employees LIMIT 0, 5;

# 2. 查询有奖金且工资较高的第11到第20名
SELECT * FROM employees WHERE commission_pct IS NOT NULL 
ORDER BY salary DESC LIMIT 10, 10;

4.9 联合查询

当查询结果来自多张表且多张表之间没有关联,此时可以用联合查询,使用union关键字

5. DDL

5.1 库的管理

# 1. 创建数据库
CREATE DATABASE stuDB;
CREATE DATABASE IF NOT EXISTS stuDB;

# 2. 删除数据库
DROP DATABASE stuDB;
DROP DATABASE IF EXISTS stuDB;

5.2 表的管理

5.2.1 创建表

5.2.1.1 语法规则

create table [if not exists] 表明 (
	字段1 字段类型 [字段约束],
	字段2 字段类型 [字段约束],
	字段3 字段类型 [字段约束],
	字段4 字段类型 [字段约束],
	字段5 字段类型 [字段约束]
);

5.2.1.2 常用数据类型

 - int:整型
 - double/float:浮点型,其中double(5, 2)表示最多有5位,其中必须含有2位小数,最大可以表示999.99
 - decimal:浮点型,在表示金钱方面可以使用该类型,不会出现精度缺失
 - varchar:表示可变长度字符,varchar(n)根据实际存储决定开辟的空间,但最大可开辟n个字符的空间
 - char:用来表示固定长度字符,char(n)不论实际存储,开辟空间都是n个字符,n可以不写,默认为1
 - text:用来表示较长文本
 - blob:字节类型
 - date:日期类型,格式为yyyy-MM-dd
 - time:时间类型,格式为hh:mm:ss
 - timestamp:时间戳,格式为yyyyMMdd hhmmss,保存范围为1970-1-1 ~ 2038-12-31,占用4个字节
 - datetime:时间戳,保存范围为1900-1-1 ~ xxxx,占用8个字节

varchar与char类型的区别:

  • varchar是可变长度存储,char是固定长度存储
  • varchar默认额外使用1个字节来存储实际存储字符数,因此在默认情况下只能存入255个字符;当存入字符超过255时,数据库会自动使用2个字节来存储实际存储的字符数,此时最多存入的字符数变为65535;需要注意的是,数据库最多使用2个字节记录字符数,因此varchar最多存入字符数为65535
  • char不会使用额外字节存储实际存入字符数量

5.2.1.3 约束

1. not null:非空约束,限制该字段为必填项
2. default:若某字段没有插入值,则自动插入默认值
3. primary key:主键,限制该字段不能重复,默认不能为空;一张表只能有一个主键,可以是多个字段的组合主键
4. unique:唯一,限制字段值不能重复
5. check:限制字段必须满足指定条件
6. foreign key:外键,限制两个表的关系,要求外键列的值必须来自主表的关联列,主、从表关联列的类型必须一致,
意思一样,但名称无要求,同时,主表的关联列必须是主键

5.2.1.4 示例

# 创建表
CREATE TABLE IF NOT EXISTS stuinfo(
	stu_id INT PRIMARY KEY, # 主键约束
	stu_name VARCHAR(20) UNIQUE NOT NULL, # 唯一约束、非空约束
	stu_gender CHAR(1) DEFAULT '男', # 默认约束
	stu_email VARCHAR(20) NOT NULL, # 非空约束
	stu_age INT CHECK(age BETWEEN 0 AND 100), # 检查约束
	stu_major_id INT,
	CONSTRAINT fk_stuinfo_major FOREIGN KEY(stu_major_id) REFERENCES major(id) # 外键约束
);

5.2.2 修改表

5.2.2.1 语法规则

alter table 表明 add|modify|change|drop column 字段名 字段类型 [约束]

5.2.2.2 示例

# 1. 修改表名
alter table stuinfo rename to students;

# 2. 添加字段
alter table students add column birthdate timestamp not null;

# 3. 修改字段名
alter table students change column birthdate birthday datetime null;

# 4. 修改字段类型
alter table students modify column birthday timestamp;

# 5. 删除字段
alter table students drop column birthday;

5.2.3 删除表

drop table if exists students;

5.2.4 复制表

# 1. 复制表结构
create table 新表名 like 旧表名;

# 2. 复制表结构和数据
create table 新表名 select * from 表名;

# 3. 复制某个表中的某几个字段到新表中
# 原理:select语句会将oldTable中对应字段、对应字段的所有数据都会查询出来,
# 并复制到newTable中,我们只需要使select查询出来的没有数据即可,因此加上条
# 件1 = 2
create table newTable select column1, column2 from oldTable where 1 = 2;

6. DML

6.1 插入数据

# 插入语句

# 插入单行数据
insert into 表名 (column1, column2 ...) values (value1, value2 ...)

# 插入多行数据
# 这样的方式插入多行数据,只对服务器递交了单次请求
insert into 表名 (column1, column2 ...) values (value1, value2 ...), (value1, value2 ...) ...

6.2 修改数据

# 修改数据
alter table 表名 set column1 = 新值, column2 = 新值 ... where 条件

6.3 数据删除

6.3.1 示例

# 删除数据

# 1. delete,根据条件删除表中数据
delete from 表名 where 条件

# 2. truncate,删除表中所有数据
truncate table 表名

6.3.2 truncate与delete区别

  1. delete操作需要进行事务提交,可以做回滚,truncate操作一次性删除表中所有数据,且删除行不可恢复
  2. truncate操作后会返还数据所占空间,如自增长重新计数等,但delete操作不会
发布了9 篇原创文章 · 获赞 7 · 访问量 3188

猜你喜欢

转载自blog.csdn.net/weixin_42806169/article/details/104432050