MySQL 学习(前2天)

课程链接:【尚硅谷】MySQL基础入门教程丨数据库实战(sql数据库优化)

笔记整理链接:https://blog.csdn.net/m0_46153949/article/details/107116168

数据库

为什么要学数据库?

  • 实现数据持久化
  • 使用完整的管理系统统一管理,易于查询

DB 数据库(database):存储数据的仓库

DBMS 数据库管理系统(Database Management System)

SQL 结构化查询语言(Structure Query Language)

  1. DML(Data Manipulation Language):数据库操纵语句,用于添加、删除、修改、查询数据库记录,并检查数据完整性
  2. DDL(Data Definition Language):数据定义语句,用于库和表的创建、修改、删除
  3. DCL(Data Control Language):数据控制语句,用于定义用户的访问权限和安全级别

DML 用于查询与修改数据记录,包括如下 SQL 语句:

  • INSERT:添加数据到数据库中
  • UPDATE:修改数据库中的数据
  • DELETE:删除数据库中的数据
  • SELECT:选择(查询)数据

DDL 用于定义数据库的结构,比如创建、修改或删除数据库对象,包括如下 SQL 语句:

  • CREATE TABLE:创建数据库表
  • ALTER TABLE:更改表结构、添加、删除、修改列长度
  • DROP TABLE:删除表
  • CREATE INDEX:在表上建立索引
  • DROP INDEX:删除索引

DCL 用来控制数据库的访问,包括如下 SQL 语句:

  • GRANT:授权访问权限
  • REVOKE:撤销访问权限
  • COMMIT:提交事务处理
  • ROLLBACK:事务处理回退
  • SAVEPOINT:设置保存点
  • LOCK:对数据库的特定部分进行锁定

MySQL使用

右击计算机——管理——服务——启动/停止 MySQL 服务

net start mysql # 启动
net stop mysql # 停止
mysql -h 主机名 -u 用户名 -p密码 # h与主机名可有可无空格,u与用户名可有可无空格,p与密码无空格
exit # 退出

MySQL 语法规范:

  1. 不区分大小写
  2. 每句话用 ;\g 结尾
  3. 各子句一般分行写
  4. 关键字不能缩写也不能分行
  5. 用缩进提高语句的可读性
# 显示数据库
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
5 rows in set (0.00 sec)

# 使用test数据库
mysql> use test;
Database changed
mysql> show tables;
Empty set (0.00 sec)

# 新建一个customer数据库
mysql> create table customer(
    -> id varchar(10),
    -> age int,
    -> name varchar(30));
Query OK, 0 rows affected (0.29 sec)

# 查看指定数据库中有哪些数据表
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| customer       |
+----------------+
1 row in set (0.00 sec)

# 查看customer表结构
mysql> desc customer;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | varchar(10)  | YES  |     | NULL    |       |
| age   | int(11)     | YES  |     | NULL    |       |
| name  | varchar(30) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

# 删除customer表
mysql> drop table customer;
Query OK, 0 rows affected (0.19 sec)

# 查看指定数据库中有哪些数据表
mysql> show tables;
Empty set (0.00 sec)
  • 对条件查询的数据可以使用 where 字句过滤

    % 匹配任意多个字符

    _ 只匹配一个字符

# 向表中插入记录
mysql> insert into customer(id, age, name)
    -> values('100', 11, 'Dog'),('101', 12, 'Cat'),('102', 13, 'Bird');
Query OK, 3 rows affected (0.07 sec)
Records: 3  Duplicates: 0  Warnings: 0

# 查询所有列
mysql> select * from customer;
+------+------+------+
| id   | age  | name |
+------+------+------+
| 100  |   11 | Dog  |
| 101  |   12 | Cat  |
| 102  |   13 | Bird |
+------+------+------+
3 rows in set (0.00 sec)

# 修改记录
mysql> update customer
    -> set age = 16, name = 'Lion' where id = '101';
Query OK, 1 row affected (0.10 sec)
Rows matched: 1  Changed: 1  Warnings: 0

# 查询所有列
mysql> select * from customer;
+------+------+------+
| id   | age  | name |
+------+------+------+
| 100  |   11 | Dog  |
| 101  |   16 | Lion |
| 102  |   13 | Bird |
+------+------+------+
3 rows in set (0.00 sec)

# 删除记录
mysql> delete from customer where id = '101';
Query OK, 1 row affected (0.44 sec)

# 查询所有列
mysql> select * from customer;
+------+------+------+
| id   | age  | name |
+------+------+------+
| 100  |   11 | Dog  |
| 102  |   13 | Bird |
+------+------+------+
2 rows in set (0.00 sec)

# 过滤查询
mysql> select * from customer
    -> where name like '%o%';
+------+------+------+
| id   | age  | name |
+------+------+------+
| 100  |   11 | Dog  |
+------+------+------+
1 row in set (0.00 sec)

数据处理之查询

注意:

  1. SQL 语言大小写不敏感
  2. SQL 可以写在一行或者多行
  3. 关键字不能被缩写也不能分行
  4. 各子句一般要分行写
  5. 使用缩进提高语句的可读性

使用 describe 命令,表示表结构 desc tablename

基础查询

语法:select 查询列表 from 表名

  • 查询列表可以是:表中的字段、常量值、表达式、函数
  • 查询的结果是一个虚拟的表格
# 选择所有列
SELECT * FROM `departments`;
# 选择特定列
SELECT department_id, location_id FROM departments;

别名

  1. 便于理解
  2. 如果要查询的字段有重名情况,使用别名区分
# 方式1:使用AS
SELECT last_name AS name FROM employees;
# 方式2:使用空格
SELECT last_name 姓, first_name 名 FROM employees;

去重 distinct

select distinct department_id from employees;

+ 作用

Java 中的 +

  1. 运算符:两个操作数都为数据型
  2. 连接符:只要有一个操作数为字符串

MySQL 中的 +

  • 只能作为运算符
# 两个操作数都为数值型,做加法运算
select 100+90 # 190
# 其中一方为字符串,如果转换成功,继续做加法运算
select '123'+90 # 213
# 如果转换失败,则将字符型数值转换成0
select 'john'+90 # 90
# 只要其中一方为null,则结果肯定为null
select null+0 # null

concat 拼接函数

SELECT CONCAT(last_name, first_name) AS 姓名 FROM employees

条件查询

语法:select 查询列表 from 表名 where 筛选条件

分类:

  1. 按条件表达式筛选:

    > < = != <> >= <=

# 查询部门编号不等于90号的员工名和部门编号
select last_name, department_id from employees where department_id<>90
  1. 按逻辑表达式筛选:

    `&& || ~``

    ``and or not`

# && 和 and:两个条件都为true,结果为true,反之为false
# || 和 or:只要有一个条件为true,结果为true,反之为false
# ! 和 not:如果连接的条件本身为false,结果为true,反之为false

# 查询工资z在10000到20000之间的员工名、工资及奖金
SELECT last_name, salary, commission_pct FROM employees WHERE salary>=10000 AND salary<=20000
# 查询部门编号不是在90-110之间,或者工资高于15000的员工信息
SELECT * FROM employees WHERE department_id < 90 OR department_id > 110 OR salary > 15000
  1. 模糊查询:

    (not) like(not) between and(not) inis (not) null

USE myemployees
/*
like: 一般和通配符搭配使用
    % 任意多个字符,包含0个字符
    _ 任意单个字符
*/

# 查询员工名中包含字符a的员工信息
SELECT * FROM employees WHERE last_name LIKE '%a%'
# 查询员工名中第三个字符为b,第五个字符为a的员工名和工资
SELECT last_name, salary FROM employees WHERE last_name LIKE '__n_l%'
# 查询员工名种第二个字符为_的员工名
SELECT last_name FROM employees WHERE last_name LIKE '_\_%'

/*
between and:判断某字段的值是否属于某个区间
    ① 提高语句简洁度
    ② 包含临界值
    ③ 两个临界值不要调换顺序
*/
# 查询员工编号在100到120之间的员工信息
SELECT * FROM employees WHERE employee_id >= 100 AND employee_id <= 120
SELECT * FROM employees WHERE employee_id BETWEEN 100 AND 120

/*
in:判断某字段的值是否属于列表中的某一项
    ① 提高语句简洁度
    ② in列表的值类型必须一致或兼容
*/
# 查询员工的工种编号是IT_PROG、AD_VP、AD_PRES中的一个员工名和工种编号
SELECT last_name, job_id FROM employees WHERE job_id = 'IT_PROG' OR job_id = 'AD_VP' OR job_id = 'AD_PRES'
SELECT last_name, job_id FROM employees WHERE job_id IN ('IT_PROG', 'AD_VP', 'AD_PRES')

/*
is null:判断null值
    = 或 <> 不能判断null值
    is null 或 is not null 可以判断null值
*/
# 查询没有奖金的员工名和奖金率
SELECT last_name, commission_pct FROM employees WHERE commission_pct IS NULL
SELECT last_name, commission_pct FROM employees WHERE commission_pct IS NOT NULL

/*
安全等于<=>
    安全等于可以判断普通类型的值和null值
*/
# 查询没有奖金的员工名和奖金率
SELECT last_name, commission_pct FROM employees WHERE commission_pct <=> NULL
SELECT last_name, commission_pct FROM employees WHERE salary <=> 12000

排序查询

语法:select 查询列表 from 表名 where 筛选条件 order by 排序列表

特点:

  1. asc(ascend) 代表升序(默认),desc(descend8) 代表降序
  2. order by 子句可以支持单个字段、多个字段、表达式、函数、别名
  3. order by 子句一般是放在查询语句的最后面
# 查询员工信息,要求工资从高到低排序
SELECT * FROM employees ORDER BY salary DESC;
# 查询部门编号是>=90,按入职时间的先后进行排序【添加筛选条件】
SELECT * FROM employees WHERE department_id >= 90 ORDER BY hiredate ASC;
# 按年薪的高低显示员工的信息和年薪【按表达式排序】
SELECT *, salary * 12 * (1 + IFNULL(commission_pct, 0)) 年薪 FROM employees 
ORDER BY salary * 12 * (1 + IFNULL(commission_pct, 0));
# 按年薪的高低显示员工的信息和年薪【按别名排序】
SELECT *, salary * 12 * (1 + IFNULL(commission_pct, 0)) 年薪 FROM employees
ORDER BY 年薪 DESC;
# 按姓名的长度显示员工的姓名和工资【按函数排序】
SELECT LENGTH(last_name) 字节长度, last_name, salary FROM employees
ORDER BY LENGTH(last_name) DESC;
# 查询员工共信息,要求按工资排序,再按员工编号排序【按多个字段排序】
SELECT * FROM employees ORDER BY salary ASC, employee_id DESC;

常见函数

概念:类似于 java 的方法,将一组逻辑语句封装在方法体中,对外暴露方法名

好处:1. 隐藏了实现细节 2. 提高了代码的复用性

调用:select 函数名(实参列表)from 表

分类:

  1. 单行函数

    如:concat、length、ifnull 等

  2. 分组函数

    做统计使用

字符函数

# 1.length 获取参数值的字节值(中文两个字节、英文1个字节)
select length('狮子lion')
show variables like '%char%'

# 2.concat 拼接字符串
select concat(last_name, '_', first_name) 姓名 from employees

# 3.upper:大写 lower:小写
select upper('lion')
select lower('LION')

# 4.substr string(从1开始计数)
select substr('this is tiger', 4) out_put
# 姓名中首字符大写,其他字符小写,然后用_拼接,显示出来
select concat(upper(substr(last_name, 1, 1)), lower(substr(last_name, 2)), '_', lower(first_name)) 姓名 from employees

# 5.instr 获取子串第一次出现的索引,找不到返回0
select instr('this is lion', 'lion') as out_put

# 6.trim 去前后空格
select length(trim('  cat  ')) as out_put
select trim('+' from '+++li+++on+++') as out_put

# 7.lpad 用指定的字符实现左填充指定长度
select lpad('dog', 8, '+') as out_put

# 8.rpad 用指定的字符实现右填充指定长度
select rpad('dog', 8, '-') as out_put

# 9.replace 替换
select replace('you are a lucky bird', 'bird', 'dog') as out_put

数学函数

# 1.round 四舍五入
SELECT ROUND(1.45)
SELECT ROUND(1.567, 2)

# 2.ceil 向上取整,返回>=该参数的最小整数
SELECT CEIL(1.05)
SELECT CEIL(-1.02)

# 3.floor 向下取整,返回<=该参数的最大整数
SELECT FLOOR(-9.9)

# 4.truncate 截断
SELECT TRUNCATE(1.65, 1)

# 5.mod 取余
SELECT MOD(10, 3)

# 6.rand 随机数(0-1)
SELECT(RAND())

日期函数

格式符 功能
%Y 四位的年份
%y 2位的年份
%m 月份(01、02…11、12)
%c 月份(1,2,11,12)
%d 日(01,02)
%H 小时(24小时制)
%h 小时(12小时制)
%i 分钟(00,01…59)
%s 秒(00,01…59)
# 1.now 返回当前系统时间+日期
SELECT NOW()

# 2.curdate 返回当前系统日期,不包含时间
SELECT CURDATE()

# 3.curtime 返回当前时间,不包含日期
SELECT CURTIME()

# 4.year 返回年
SELECT YEAR(NOW())# 5.month 返回月
SELECT MONTH(NOW())SELECT MONTHNAME(NOW())# 6.day 返回日
SELECT DAY(NOW())
SELECT DATEDIFF('2020/06/30', '2020/06/21')

# 7.str_to_date 将日期格式字符转换成指定格式的日期
SELECT STR_TO_DATE('2020-5-13', '%Y-%c-%d') AS out_put
# 查询入职日期为1992-4-3的员工信息
SELECT * FROM employees WHERE hiredate = '1992-4-3'

# 8.date_format 将日期转换成字符
SELECT DATE_FORMAT(NOW(), '%y年%m月%d日') AS out_put

# 查询有奖金的员工名和入职日期(xx月/xx日 xx年)
SELECT last_name, DATE_FORMAT(hiredate, '%m月/%d日 %y年') 入职日期 FROM employees WHERE commission_pct IS NOT NULL

其他函数

# 当前数据库服务器版本
SELECT VERSION()

# datebase 当前打开的数据库
SELECT DATABASE()

# user 当前用户
SELECT USER()

# md5 返回字符型md5加密形式
SELECT MD5('a')

流程控制函数

# if函数
select if(10<5, '大', '小') 判断大小
select last_name, commission_pct, if(commission_pct is null, '没奖金', '有奖金') 备注 from employees

# case函数使用一:switch case效果
/*
java中
  switch(变量或表达式){
    case 变量1: 语句; break;
    ...
    default: 语句n; break;  
  }

mysql中
  case 要判断的变量或表达式
  when 变量1 then 要显示的值1或语句1
  ...
  eles 要显示的值n或语句n
  end
*/

/*
查询员工的工资,要求:
  部门号=30,显示的工资为1.1倍
  部门号=40,显示的工资为1.2倍
  部门号=50,显示的工资为1.3倍
  其他部门,显示的工资为原工资
*/
select salary 原始工资, department_id, case department_id 
when 30 then salary * 1.1
when 40 then salary * 1.2
when 50 then salary * 1.3
else salary
end as 新工资
from employees

# case函数使用二:类似多重if
/*
java中
  if(条件1){
    语句1;
  }else if(条件2){
    语句2  
  }
  ...
  else{
    语句n;
  }

mysql中
  case 要判断的变量或表达式
  when 条件1 then 要显示的值1或语句1
  ...
  eles 要显示的值n或语句n
  end
*/

/*
查询员工的工资的情况
  如果工资>20000,显示A级别
  如果工资>15000,显示B级别
  如果工资>10000,显示c级别
  否则,显示D级别
*/
select salary, case 
when salary>20000 then 'A'
when salary>15000 then 'B'
when salary>1000 then 'C'
else 'D'
end as 工资级别
from employees

分组函数

功能:用统计使用,又称聚合函数或统计函数或组函数

分类:sum 求和、avg 平均值、max 最大值、min 最小值、count 计算个数

特点:

  1. sum、avg 一般处理数值型

    max、min、count 可以处理任何类型

  2. 以上分组函数都忽略 null 值

  3. 可以和 distinct 搭配实现去重

    select sum(distinct 字段) from 表

  4. count 函数

    count(字段):统计该字段非空值的个数

    count(*):统计结果集的行数

    count(1):新增一列全填1,统计1的个数(只要是常量值)

    效率:

    MyISAM 存储引擎下,count(*) 的效率高

    InnoDB 存储引擎下,count(*)count(1) 的效率差不多,比 count(*) 效率高

  5. 和分组函数一同查询的字段要求是 group by 后的字段

# 1.简单使用
SELECT SUM(salary) FROM employees
SELECT AVG(salary) FROM employees
SELECT MIN(salary) FROM employees
SELECT MAX(salary) FROM employees
SELECT COUNT(salary) FROM employees

SELECT SUM(salary), ROUND(AVG(salary),2) 平均, MAX(salary) 最高, MIN(salary) 最低, COUNT(salary) 个数
FROM employees;

# 2.参数支持哪些类型
SELECT SUM(last_name), AVG(last_name) FROM employees;
SELECT SUM(hiredate), AVG(hiredate) FROM employees;

SELECT MAX(last_name), MIN(last_name) FROM employees;
SELECT MAX(hiredate), MIN(hiredate) FROM employees;

SELECT COUNT(commission_pct) FROM employees;
SELECT COUNT(last_name) FROM employees;

# 3.是否忽略null
SELECT SUM(commission_pct), AVG(commission_pct), SUM(commission_pct) / 35, SUM(commission_pct) / 10 FROM employees
SELECT MAX(commission_pct), MIN(commission_pct) FROM employees

# 4.和distinct搭配
SELECT SUM(DISTINCT salary), SUM(salary) FROM employees
SELECT COUNT(DISTINCT salary), COUNT(salary) FROM employees

# 5.count函数详细介绍
SELECT COUNT(salary) FROM employees
SELECT COUNT(*) FROM employees
SELECT COUNT(1) FROM employees

# 6.和分组函数一同查询的字段有限制
SELECT AVG(salary), employee_id FROM employees

分组查询

语法:select 分组函数, 列(要求出现在group by的后面)from 表 where 筛选条件 group by 分组的列表 order by 子句

注意:查询列表必须特殊,要求是分组函数和group by后出现的字段

特点:

  1. 分组查询的筛选条件分为两类

    数据源 位置 关键字
    分组前筛选 原始表 group by子句的前面 where
    分组后筛选 分组后的结果表 group by子句的后面 having

    分组函数做条件肯定是放在 having 子句中

    能用分组前筛选的,就优先考虑使用分组前筛选

  2. group by 子句支持单个字段分组,多个字段分组(多个字段之间用逗号隔开没有顺序要求),表达式或函数(用的比较少)

  3. 也可以添加排序(排序放在整个分组查询的最后)

# 查询每个部门的平均工资
SELECT AVG(salary) FROM employees

# 查询每个工种的最高工资
SELECT MAX(salary), job_id FROM employees GROUP BY job_id

# 查询每个位置上的部门个数
SELECT COUNT(*), location_id FROM departments GROUP BY location_id

# 查询邮箱中包含a字符的,每个部门的平均工资
SELECT AVG(salary), department_id FROM employees WHERE email LIKE '%a%' GROUP BY department_id

# 查询有奖金的每个领导手下员工的最高工资
SELECT MAX(salary), manager_id FROM employees WHERE commission_pct IS NOT NULL GROUP BY manager_id

# 查询哪个部门的员工个数>2
SELECT COUNT(*), department_id FROM employees
GROUP BY department_id HAVING COUNT(*) > 2

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

# 查询领导编号>102的每个领导手写的最低工资>5000的领导编号是哪个,以及其最低工资
SELECT MIN(salary), manager_id FROM employees WHERE manager_id > 102
GROUP BY manager_id HAVING MIN(salary) > 5000

# 按员工姓名的长度分组,查询每一组的员工个数,筛选员工个数>5
SELECT COUNT(*) c, LENGTH(last_name) len_name FROM employees
GROUP BY LENGTH(last_name) HAVING c > 5


# 查询每个部门每个工种的员工的平均工资,按平均工资的高低查询
SELECT AVG(salary), department_id, job_id FROM employees WHERE department_id IS NOT NULL
GROUP BY job_id, department_id HAVING AVG(salary) > 10000 ORDER BY AVG(salary) DESC

连接查询

概念:又称多表查询,当查询的数据来自多个表时,就会用到连接查询

笛卡尔乘积现象:表1 有 m 行,表 2 有 n 行,结果 m * n 行

发生原因:没有有效的连接条件

如何避免:添加有效的连接条件

分类:

  • 按年代分类

    sql92 标准:仅仅支持内连接、sql99标准:支持内连接 + 外连接(左外和右外) + 交叉连接

  • 按功能分类

    内连接:等值连接、非等值连接、自连接

    外连接:左外连接、右外连接、全外连接

    交叉连接

sql92标准

暂停学习 SQL

猜你喜欢

转载自blog.csdn.net/qq_38689395/article/details/116538774