MySQL学习笔记

MySQL学习笔记


一、MySQL产品的介绍和安装

1、MySQL服务的启动与停止

方式一:Windows服务管理;
方式二:通过管理员运行cmd
        net start 服务名       (启动服务)
        net stop  服务名       (停止服务)

2、MySQL服务的登录和退出

方式一:通过MySQL自带的客户端(只限root);
方式二:通过cmd命令行登录
  mysql [-h主机名 -P端口] -u用户名 -p密码
进入后提示符为 mysql>
退出
  exit或ctrl+c  

3、MySQL的常见命令

1.查看当前所有的数据库
  show database;
2.打开指定的库
    use 库名;
3.查看当前库的所有表
    show tables;
4.查看其它库的所有表
    show tables from 库名;
5.创建表
    create table 表名(
        列名 列类型,
        列名 列类型,
      ...
  );
6.查看表结构
    desc 表名;
7.查看服务器的版本
    方式一:mysql提示符下输入
        SELECT version();
    方式二:命令提示符下
        mysql -- version
        或
        mysql -V
        #Linux下显示的内容:
        /*
        [root@localhost ~]# mysql --version
        mysql  Ver 14.14 Distrib 5.6.50, for Linux (x86_64) using  EditLine wrapper
        Windows下显示的内容:
        C:\Program Files\MySQL\MySQL Server 5.6\bin>mysql -V
        mysql  Ver 14.14 Distrib 5.6.50, for Win64 (x86_64)
        */

4、Mysql语法规范

MySQL的语法规范
1.不区分大小写,但建议关键字大写,表名、列名小写;
2.每条命令最好用分号结束;
3.每条命令根据需要,可以进行缩进或换行
    #示例:
    SELECT
    姓名,性别,民族,二级学院名
    FROM
    students
    WHERE 民族 <> '汉族';   
4.注释
        单行注释:#注释文字
        单行注释:-- 注释文字
        多行注释:/* 注释文字 */

二、DML语言的学习

工作原理

一:MySQL查询

#单表查询
根据where条件过滤表中的记录,每过滤一次形成一张中间表(中间表对用户是不可见的)。然后根据select的选择列返回最终的结果。
#两张表连接查询
对两表求积(笛卡尔积:行相乘,列相加)并用on条件和连接类型进行过滤形成中间表,然后根据where条件过滤中间表的记录,并且根据select指定的列返回查询结果。
#多表连接查询
先对第一个和第二个表按照两表连接做查询,然后用查询结果和第三表做连接查询,以此类推,直到所有的表都连接上为止,最终形成一个中间的结果表,然后根据where条件过滤中间表的记录,并根据select指定的列返回查询结果。

二:MySQL查询语法顺序

1:  select
2:  from
3:  left … join
4:  on
5:  where
6:  group by
7:  having
8:  order by
9:  limit

三:MySQL执行顺序

#示例:
    select * 
    from students 
    left join course c 
    on s.id = c.student_id 
    where s.id >10 
    group by s.id 
    having count(1) > 3 
    order by s.id desc 
    limit 0,100
#执行顺序:
1:form(将最近的两张表进行笛卡尔积) 形成中间表 … VT1
2:on (将VT1按照它的条件进行过滤) …VT2
3:left join (保留左表的记录) …VT3
4:where (过滤VT3中的记录,没过滤一次形成一张中间表) VT4 … VTn
5:group by (对VT4的记录进行分组) …VT5
6:having (对VT5中的记录进行过滤) …VT6
7:select (对VT6中的记录选取指定的列) …VT7
8:order by (对VT7的记录进行排序) …游标
9:limit(对排序后的值进行分页)
#注意:
where 条件执行顺序(影响性能)
1:MySQL从左向右去执行where条件
2:Oracle从右向左去执行where条件
所以,写where条件的时候,优先级高的部分要去编写过滤力度最大的条件语句。

1、基础 查询

# 基础查询
/*
语法:
SELECT 查询列表 from 表名;
特点:
1、查询列表可以是:表中的字段、常量、表达式、函数
2、查询的结果是一个虚拟的表格
*/
#1.查询表中的单个字段
SELECT last_name FROM employees;
#2.查询表中的多个字段
SELECT first_name,last_name FROM employees;
#3.查询表中的所有字段
方式一:
SELECT `emp_no`,`birth_date`,`first_name`,`last_name`,`gender`,`hire_date` FROM employees;
方式二:
SELECT * FROM employees;
注意:字段名和关键字相同时加着重号 ``    例如:SELECT `NAME` FROM employees;
#4.查询常量值
SELECT 100;
SELECT 'HongHong';  字符串加单引号
#5.查询表达式
SELECT 100%98;
SELECT 100*99;
#6.查询函数
SELECT version();
SELECT CONCAT(last_name,".",first_name) 姓名 FROM employees;
#7.起别名
方式一:使用 AS
SELECT 100%98 as 结果;
方式二:使用空格
SELECT last_name 姓,first_name 名 FROM employees;
#8.去重
案例:查询部门员工表中涉及到的所有部门编号
SELECT DISTINCT dept_no FROM dept_emp;
#9.+号的作用
MySQL中的+号:
仅仅只有一个功能:运算符
SELECT 100+90;两个操作数都为数值型,则做加法运算
SELECT '123'+90;只要其中一方为字符型,试图将字符型数值转换成数值型,如果转换成功,则继续做加法运算;
SELECT 'john'+99;如果转换失败,则字符型数值转换成0
SELECT null+100;    只要其中一方为null,则结果肯定为null

2、条件查询

#进阶2:条件查询
/*
语法:
        select 
                    查询列表
        from
                    表名
        where
                    筛选条件;
分类:
        ①、按条件表达式筛选
*/
分类:
        一、按条件表达式筛选
            简单条件运算符:
           >    <   = != <> >= <=
        二、按逻辑表达式筛选
            逻辑运算符:
                and 两个条件都为true,结果为true,反之为false 
                or  只要有一个条件为true,结果为true,反之为false
                not 如果连接的条件本身为false,结果为true,反之为false
        三、模糊查询
                like
                between and
                in 
                is null |  is not null
一、按条件表达式筛选
#案例1:查询工资大于150000的员工信息
select * from employees where salary >150000;
#案例2:查询部门编号不等于90的员工名和部门编号
select * last_name,dept_no from employees where dept_no <>90;
二、按逻辑表达式筛选
#案例1:查询工资在10000到20000之间的员工名、工资以及奖金
select 
            last_name,
            salary,
            commission_pct
from
            employees
where
            salary>=10000 and salary <=20000;
#案例2:查询部门编号不是在90到110之间,或者工资高于15000的员工信息
三、模糊查询
1. like 特点:
①一般和通配符搭配使用
            通配符:
            %   任意多个字符,包含0个字符
            _ 任意单个字符
#案例1:查询员工名中包含字符a的员工信息
select * from employees where last_name like '%a%';
#案例2:查询员工名中第三个字符为e,第五个字符为a的员工信息
select * from employees where last_name like '__e_a%';
#案例3:查询员工名中第二个字符为_的员工名
select last_name from employees where last_name like '_\_%';#用\转义一下
select last_name from employees where last_name like '_$_%' escape '$'; #escape 转义
2、 between and
/*
①使用between and提高语句的简洁度
②包含临界值
③两个临界值不能调换顺序
*/
#案例1:查询员工编号在100到120之间的员工信息
select * from employees where employee_id >=100 and employee_id <=120;
-----------------
select * from employees where employee_id between 100 and 120;
3、 in
/*
含义:判断某字段的值是否属于in列表中的某一项
特点:
        ①使用in提高语句的简洁度
        ②in列表的值类型必须一致或兼容
        ③不支持通配符
*/
#案例:查询员工的工种编号是ad_vp、it_prog、FR_MGR中的一个的员工名和工种编号
select last_name,job_id from employees where job_id = 'ad_vp' or job_id = 'it_prog' or job_id = 'FR_MGR';
-----------------
select last_name,job_id from employees where in ('ad_vp','it_prog','FR_MGR');
4、 is null/ is not null
/*
=或<>不能用于判读null值
is null或is not null 可以判断null值
*/
#案例1:查询没有奖金的员工名和奖金率
select last_name,commission_pct from employees where commission_pct is null;
#案例2:查询有奖金的员工名和奖金率
select last_name,commission_pct from employees where commission_pct is not null;
5、安全等于 <=>
#案例1:查询没有奖金的员工名和奖金率
select last_name,commission_pct from employees where commission_pct <=> null;
#案例
#查询在职员工人数
SELECT COUNT(*) FROM dept_emp WHERE to_date = '9999-01-01'; 
SELECT COUNT(*) FROM salaries WHERE to_date = '9999-01-01';
SELECT COUNT(*) FROM titles WHERE to_date = '9999-01-01';               240124人

2.1 MySQL LIKE 子句

以下是 SQL SELECT 语句使用 LIKE 子句从数据表中读取数据的通用语法:

SELECT field1, field2,...fieldN 
FROM table_name
WHERE field1 LIKE condition1 [AND [OR]] filed2 = 'somevalue'
  • 你可以在 WHERE 子句中指定任何条件。
  • 你可以在 WHERE 子句中使用LIKE子句。
  • 你可以使用LIKE子句代替等号 =
  • LIKE 通常与 % 一同使用,类似于一个元字符的搜索。
  • 你可以使用 AND 或者 OR 指定一个或多个条件。
  • 你可以在 DELETE 或 UPDATE 命令中使用 WHERE...LIKE 子句来指定条件。

2.2 MySQL WHERE 子句


语法

以下是 SQL SELECT 语句使用 WHERE 子句从数据表中读取数据的通用语法:

SELECT field1, field2,...fieldN 
FROM table_name1, table_name2...
[WHERE condition1 [AND [OR]] condition2.....
  • 查询语句中你可以使用一个或者多个表,表之间使用逗号, 分割,并使用WHERE语句来设定查询条件。
  • 你可以在 WHERE 子句中指定任何条件。
  • 你可以使用 AND 或者 OR 指定一个或多个条件。
  • WHERE 子句也可以运用于 SQL 的 DELETE 或者 UPDATE 命令。
  • WHERE 子句类似于程序语言中的 if 条件,根据 MySQL 表中的字段值来读取指定的数据。

以下为操作符列表,可用于 WHERE 子句中。

下表中实例假定 A 为 10, B 为 20

操作符 描述 实例
= 等号,检测两个值是否相等,如果相等返回true (A = B) 返回 false。
<>, != 不等于,检测两个值是否相等,如果不相等返回true (A != B) 返回 true。
> 大于号,检测左边的值是否大于右边的值, 如果左边的值大于右边的值返回true (A > B) 返回false。
< 小于号,检测左边的值是否小于右边的值, 如果左边的值小于右边的值返回true (A < B) 返回 true。
>= 大于等于号,检测左边的值是否大于或等于右边的值, 如果左边的值大于或等于右边的值返回true (A >= B) 返回false。
<= 小于等于号,检测左边的值是否小于或等于右边的值, 如果左边的值小于或等于右边的值返回true (A <= B) 返回 true。

3、排序查询

#进阶3:排序查询
/*
引入
        select * from employees; #排序
语法:
            select 查询列表
            from 表
            【where 筛选条件】
            order by 排序列表【asc|desc】
特点:
            1、asc代表升序,desc代表的是降序,如果不写,默认为升序
            2、order by子句中可以支持单个字段、多个字段、表达式、函数、别名
            3、order by一般放在查询语句的最后面,limit子句除外
*/
#案例1:查询员工信息,要求按工资从高到低排序
select * from employees order by salary desc;
#案例2:查询部门编号>=90的员工信息,按入职时间的先后进行排序【添加筛选条件】
select * from employees where department_id >=90 order by hiredate asc;
#案例3:按年薪的高低显示员工的信息和年薪【按表达式排序】
select *,salary*2*(1+ifnull(commission_pct,0)) as 年薪
from    employees
order by salary*2*(1+ifnull(commission_pct,0)) desc;
#案例4:按年薪的高低显示员工的信息和年薪【按别名排序】
select *,salary*2*(1+ifnull(commission_pct,0)) as 年薪
from    employees
order by 年薪 desc;  
#案例5:按姓名的长度显示员工的姓名和工资【按函数排序】
select length(last_name) 字节长度,last_name,salary
from employees
order by length(last_name) desc;
#案例6:查询员工信息,要求先按工资排序,再按员工编号排序【按多个字段排序】
select * 
from employees
order by salary asc,employee_id desc;

4、常见函数

#进阶4:常见函数
/*
概念:类似java的方法,将一组逻辑语句封装在方法体中,对外暴露方法名
好处:1、隐藏了实现细节 2、提高代码的重要性
调用:select 函数(实参列表) 【from 表】;
特点:
        ● 叫什么(函数名)
        ● 干什么(函数功能)
分类:
        1、单行函数
        ● 字符函数
        ● 数学函数
        ● 日期函数
        ● 其他函数【补充】
        ● 流程控制函数【补充】
        2、分组函数
        功能:做统计使用,又称为统计函数、聚合函数、组函数
*/

一、字符函数

1. length(str)字符串长度
select length('john');
select length('Hello!Mr.张');
show variables like '%char%' #中文字节的长度与字符集有关
2. concat 拼接字符串
select concat(last_name,'_',fist_name) 姓名 from employees;
3. upper、lower
select upper('john');
select lower('Rose');
#示例:将姓变大写,名变小写,然后拼接
select concat(upper(last_name),lower(first_name)) 姓名 from employees;
4. substr、substring
select substr('元芳你怎么看?',3) as 结果;
#截取从指定索引处后面所有字符
select substr('李莫愁爱上了陆展元',1,3) as 结果;
#截取从指定索引处指定字符长度的字符
#示例:姓名中首字母大写,其他字符小写然后用_拼接,显示出来
select concat(upper(sbustr(last_name,1,1)),'_',lower(substr(last_name,2))) 姓 from employees;
5. instr 返回字符串第一次出现的索引,如果找不到返回0
select instr('我是菜鸟,我爱学习','我爱') as out_put;
6. trim 掐头去尾
select trim('    去除前后空格    ') as out_put;
select trim('a' from 'aaaaa去除前后字符aaaaaaaaaaaaa') as out_put;
7. lpad 用指定的字符实现左填充指定长度
select lpad('我是菜鸟',10,'*') as out_put;
8. rpad 用指定的字符实现左填充指定长度
select rpad('我是菜鸟',12,'ab') as out_put;
select rpad('我是菜鸟',2,'0') as out_put;
9. replace 替换
select replace('我是菜鸟,我爱学习','菜鸟','新手') as 结果;
select replace('我是菜鸟,我爱学习','我','你') as 结果;

二、数学函数

1. round 四舍五入
select round(1.65);
select round(-1.45);
select round(1.567,2);
2. ceil 向上取整,返回>=该参数的最小整数
select ceil(1.52);
select ceil(1.000001);
select ceil(-1.02);
3. floor 向下取整,返回<=该参数的最大整数
select floor(9.99);
select floor(-9.99);
4. truncate 截断
select truncate(1.69999,1);
5. mod 取余
mod(a,b) : a-a/b*b
mod(-10,-3)
mod(10,-3) 
select mod(10,3);
6. cast 十六进制转十进制
SELECT CAST(0xC2A0 AS UNSIGNED);

三、日期函数

1. now 返回当前系统日期+时间
select now();
2. curdate 返回当前系统日期,不包含时间
select curdat();
3. curtime 返回当前系统时间,不包含日期
select curtime();
4. year 获取指定部分的年、月、日、小时、分钟、秒
select year(now()) 年;
select year('1998-1-1') 年;
select year(hiredate) 年 from employees;
select month(now()) 月;
select monthname(now()) 月;
5. str_to_date 将字符转换成日期
select str_to_date('2020-3-3','%Y-%c-%d') as out_put;
#案例:查询入职日期为1992-4-3的员工信息
select * from employees where hiredate ='1992-4-3';
select * from employees where hiredate = str_to_date ('4-3 1992','%c-%d %Y');
6. date_format将日期转换成字符
select date_format(now(),'%Y年%m月%d日') as out_put;
select date_format('2021/9/3','%Y年%m月%d日') as out_put;
#案例:查询有奖金的员工名和入职日期(xx月/xx日 xxxx年)
select last_name date_format(hiredat,'%m月/%d日 %Y年') 入职日期
from employees
where commission_pct is not null;

日期格式符对照表:

序号 格式符 功能
1 %Y 4位的年份
2 %y 2位的年份
3 %m 月份(01,02...11,12)
4 %c 月份(1,2,3...11,12)
5 %d 日(01,02...)
6 %H 小时(24小时制)
7 %h 小时(12小时制)
8 %i 分钟(00,01..59)
9 %s 秒(00,01...59)

5、分组函数

一、聚合函数(aggregation function)---也就是组函数

在一个行的集合(一组行)上进行操作,对每个组给一个结果。

常用的组函数:

AVG([distinct] expr) 求平均值
COUNT({*|[distinct] } expr) 统计行的数量
MAX([distinct] expr) 求最大值
MIN([distinct] expr) 求最小值
SUM([distinct] expr) 求累加和

①每个组函数接收一个参数

②默认情况下,组函数忽略列值为null的行,不参与计算

③有时,会使用关键字distinct剔除字段值重复的条数

注意:

1)当使用组函数的select语句中没有group by子句时,中间结果集中的所有行自动形成一组,然后计算组函数;

2)组函数不允许嵌套,例如:count(max(…));

3)组函数的参数可以是列或是函数表达式;

4)一个SELECT子句中可出现多个聚集函数。

min()

max()

count()


6、分组查询

//语法:
            SELECT 分组函数,列(要求出现在group by的后面)
            from 表
            [where 筛选语句]
            group by  分组的列表 #支持字段、多字段、表达式或函数
            [having ]
            [order by 子句]
注意:
            查询列表必须特殊,要求是分组函数和group by后出现的字段
特点:
            1、分组查询中的筛选条件分为两类
                                     数据源                        位置                              关键字
            分组前筛选           原始表                     group by 子句的前面      where
            分组后筛选           分组后的结果集         group by 子句的后面      having
1.按字段名分组
#查询全名重名的员工全名和人数
方法一:
SELECT CONCAT(first_name,'.',last_name) AS quanming,COUNT(*) AS 人数
FROM employees
GROUP BY quanming
HAVING 人数>1
ORDER BY 人数 DESC
LIMIT 100;
方法二:
SELECT first_name,last_name,COUNT(*)
FROM employees
GROUP BY first_name,last_name
HAVING COUNT(*)>1
ORDER BY COUNT(*) DESC
LIMIT 100;
#查询每个职位的人数
SELECT title,COUNT(*)
FROM titles
GROUP BY title
ORDER BY COUNT(*) DESC
LIMIT 100;
#查询调换过部门的员工编号和次数  通过查询可以看到没有超过调换3次数部门的员工
SELECT emp_no,COUNT(*)
FROM dept_emp
GROUP BY emp_no
HAVING COUNT(*)>1
ORDER BY emp_no;
2.按表达式或函数分组
#案例1:按照员工姓名长度分组,查询每一组的人数,筛选人数大于
SELECT LENGTH(CONCAT(first_name,last_name)) len_name ,COUNT(*)
FROM employees
GROUP BY LENGTH(CONCAT(first_name,last_name))
HAVING COUNT(*)>0
ORDER BY COUNT(*) ;
#案例1验证
SELECT * 
FROM employees
WHERE LENGTH(CONCAT(first_name,last_name))=27;

7、连接查询

7.1 SQL92语法

只支持内连接
        等值连接
     非等值连接
     自连接 
#示例
1、等值连接
#查询在职员工编号为10001——10009之间的部门信息
SELECT emp_no,d.dept_no,d.dept_name,from_date,to_date
FROM dept_emp de,departments d
WHERE de.`dept_no`=d.`dept_no` AND to_date = '9999-01-01' AND emp_no BETWEEN 10001 AND 10009
ORDER BY de.emp_no;
2、非等值连接

3、自连接

7.2 SQL99语法

/*语法
            select 查询列表
            from 表1 别名 【连接类型】
            join 表2 别名
            on 连接条件
            【where 筛选条件】
            【group by 分组】
            【having 筛选条件】
            【order by 排序列表】
*/
连接类型分类:
1.内连接           inner
        等值连接
     非等值连接
     自连接 
2.外连接
         左外连接       left    【outer】 左边的是主表
         右外连接       right 【outer】   右边的是主表
         全外连接       full    【outer】  mysql不支持
3.交叉连接      cross
#————————————————————————————————————————————————————#
/*外连接
#应用场景:用于查询一个表中有,另一个表没有的记录
特点:
1、外连接的查询结果为主表中的所有记录
        如果从表中有和它匹配的,则显示匹配的值
        如果从表中没有和它匹配的,则显示null
        外连接查询结果=内连接结果+主表中有而从表没有的记录
2、左外连接,left join 左边的是主表
   右外连接,right join 右边的是主表
3、左外和右外交换两个表的顺序,可以实现同样的效果
*/

7.3 示例

示例
1.内连接
#案例1:
SELECT emp_no,d.dept_no,d.dept_name,from_date,to_date
FROM dept_emp de
JOIN departments d
ON de.`dept_no`=d.`dept_no` 
WHERE to_date = '9999-01-01' AND emp_no BETWEEN 10001 AND 10009
ORDER BY de.emp_no;
#案例2:查询现任部门经理编号
SELECT emp_no,dept_name,to_date
FROM dept_manager m
JOIN departments d
ON m.`dept_no`=d.`dept_no`
WHERE m.`to_date` = '9999-01-01';
#案例3:查询现任部门经理全名
SELECT dept_name 部门名,CONCAT(first_name,'.',last_name) 部门经理
FROM dept_manager m
JOIN departments d
JOIN employees e
ON m.`dept_no`=d.`dept_no` AND m.`emp_no`=e.`emp_no`
WHERE m.`to_date` = '9999-01-01';
#案例4:查询编号为10010的员工全名,性别、部门名称、部门经理、薪酬
SELECT CONCAT(e.first_name,'.',e.last_name) 员工名,e.gender 性别,d.dept_name 部门,CONCAT(em.first_name,'.',em.last_name) 部门经理,salary 工资
FROM employees e
JOIN dept_emp de
JOIN departments d
JOIN salaries s
JOIN dept_manager m
JOIN employees em
ON e.`emp_no`=de.`emp_no` AND de.`dept_no`= d.`dept_no`AND e.`emp_no`=s.`emp_no` AND m.`dept_no`= d.`dept_no` AND m.`emp_no`=em.`emp_no`
WHERE s.`to_date` = '9999-01-01' AND m.`to_date`  = '9999-01-01' AND de.`to_date` ='9999-01-01' AND e.emp_no = 10010;
2、自连接
#案例1:查询编号为10010的员工全名及部门经理
SELECT CONCAT(e.first_name,'.',e.last_name) 员工名,CONCAT(em.first_name,'.',em.last_name) 部门经理
FROM employees e
JOIN dept_emp de
JOIN dept_manager m
JOIN employees em
ON e.`emp_no`=de.`emp_no` AND de.`dept_no`= m.`dept_no`AND m.`emp_no`=em.`emp_no` 
WHERE  m.`to_date`  = '9999-01-01' AND de.`to_date` ='9999-01-01' AND e.emp_no = 10010;
3、交叉连接
#表1和表2笛卡尔积
SELECT *
FROM departments
CROSS JOIN dept_manager;
4、左外连接
#查询没有男友的女主
SELECT b.`name` 女主,boys.`boyname` 男神
FROM `beauty` b
LEFT JOIN boys 
ON b.`boyfriend_id`=boys.`id`
WHERE boys.`boyname` IS NULL
ORDER BY boys.`boyname`;
5、右外连接
#查询打光棍的男神
SELECT b.`name` 女主,boys.`boyname` 男神
FROM `beauty` b
RIGHT JOIN boys 
ON b.`boyfriend_id`=boys.`id`
WHERE b.`name`IS NULL
ORDER BY boys.`boyname`;

7.4 girls数据库

#创建girls数据库
/*
SQLyog Ultimate
MySQL - 5.6.50-log : Database - girls
*********************************************************************
*/

/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`girls` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_bin */;

USE `girls`;

/*Table structure for table `beauty` */

DROP TABLE IF EXISTS `beauty`;

CREATE TABLE `beauty` (
  `id` int(11) NOT NULL,
  `name` varchar(50) COLLATE utf8_bin NOT NULL,
  `sex` char(1) COLLATE utf8_bin DEFAULT NULL,
  `borndate` datetime DEFAULT NULL,
  `phone` varchar(11) COLLATE utf8_bin DEFAULT NULL,
  `photo` blob,
  `boyfriend_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

/*Data for the table `beauty` */

insert  into `beauty`(`id`,`name`,`sex`,`borndate`,`phone`,`photo`,`boyfriend_id`) values 
(1,'盛明兰','女',NULL,NULL,NULL,1),
(2,'盛墨兰','女',NULL,NULL,NULL,12),
(3,'盛如兰','女',NULL,NULL,NULL,13),
(4,'盛老太太',NULL,NULL,NULL,NULL,NULL),
(5,'盛淑兰',NULL,NULL,NULL,NULL,NULL),
(6,'小秦氏',NULL,NULL,NULL,NULL,5),
(7,'朱曼娘',NULL,NULL,NULL,NULL,1),
(8,'盛华兰',NULL,NULL,NULL,NULL,NULL),
(9,'王若弗',NULL,NULL,NULL,NULL,2),
(10,'平宁郡主',NULL,NULL,NULL,NULL,10),
(11,'小桃',NULL,NULL,NULL,NULL,14),
(12,'卫小娘',NULL,NULL,NULL,NULL,2),
(13,'白氏',NULL,NULL,NULL,NULL,5),
(14,'沈皇后',NULL,NULL,NULL,NULL,15),
(15,'刘贵妃',NULL,NULL,NULL,NULL,15),
(16,'林噙霜',NULL,NULL,NULL,NULL,2),
(17,'常嬷嬷',NULL,NULL,NULL,NULL,NULL),
(18,'周雪娘',NULL,NULL,NULL,NULL,NULL),
(19,'孔嬷嬷',NULL,NULL,NULL,NULL,NULL),
(20,'盛品兰',NULL,NULL,NULL,NULL,NULL),
(21,'丹橘',NULL,NULL,NULL,NULL,NULL),
(22,'申和珍',NULL,NULL,NULL,NULL,16);

/*Table structure for table `boys` */

DROP TABLE IF EXISTS `boys`;

CREATE TABLE `boys` (
  `id` int(11) NOT NULL,
  `boyname` varchar(20) COLLATE utf8_bin DEFAULT NULL,
  `userCP` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

/*Data for the table `boys` */

insert  into `boys`(`id`,`boyname`,`userCP`) values 
(1,'顾廷烨',0),
(2,'盛紘',NULL),
(3,'盛长柏',NULL),
(4,'盛长枫',NULL),
(5,'顾偃开',NULL),
(6,'顾廷煜',NULL),
(7,'贺弘文',NULL),
(8,'顾四爷',NULL),
(9,'顾五爷',NULL),
(10,'齐国公',NULL),
(11,'顾廷炳',NULL),
(12,'梁晗',NULL),
(13,'文炎敬',NULL),
(14,'石头',NULL),
(15,'新帝赵宗全',NULL),
(16,'齐衡',NULL);

/*Table structure for table `roles` */

DROP TABLE IF EXISTS `roles`;

CREATE TABLE `roles` (
  `id` int(11) NOT NULL,
  `rolename` varchar(20) COLLATE utf8_bin DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

/*Data for the table `roles` */

insert  into `roles`(`id`,`rolename`) values 
(1,'盛名兰'),
(2,'顾廷烨'),
(3,'齐衡'),
(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,'刘贵妃');

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

8、子查询

定义:出现在其他语句中的select语句,称为子查询或内查询
外部的查询语句,称为主查询或外查询
分类:
按子查询出现的位置:
        select 后面
                        仅支持标量子查询
        from 后面
                        支持表子查询
        where 或 having 后面
                        标量子查询
                        列子查询
                        行子查询
        exists 后面  #(又称相关子查询)
                        表子查询
按结果接的行列数不同分为:
            #标量子查询(结果集只有一行一列)
            #列子查询(结果集只有一列多行)
            #行子查询(结果集有一行多列)
            #表子查询(结果集一般为多行多列)
#案例
1、标量子查询

2、列子查询

3、行子查询

4、表子查询

9、分页查询

#语法
select 查询列表
from 表
【连接类型】 join 表
on 连接条件
where 筛选条件
group by 分组列表
having 分组后筛选条件
order by 排序字段
limit 【offset,】size;    
/*
注释:offset要显示条目的起始索引(起始索引从0开始)
             size要显示的条目个数  
*/
#特点
        ①limit语句放在查询语句的最后
        ②offset计算公示
        要显示的页数 page,每页显示的条目数size
        
        select 查询列表
        from 表
        limit (page-1)*size,size
#案例:查询第100到150的员工信息
SELECT
  *
FROM
  employees
LIMIT 99, 51;

10、union联合查询

#案例1:
SELECT id,`name` FROM beauty
UNION ALL
SELECT id,boyname FROM boys
ORDER BY id DESC;

11、示例集

1.查询调过部门的在职员工编号及次数

2.
3.

三、DML语言的学习

1、插入语句

/*语法:
方式一:
insert into 表名(列名,...) values(值1,...)
①支持插入子查询
②支持插入多行
方式二:
insert into 表名
set 列名=值,列名=值,...
*/

#插入记录方式一:
#1.插入的值的类型必须与列的类型一致或兼容 
insert  into `roles`(`id`,`rolename`) values 
(1,'盛名兰'),
(2,'林噙霜'),
(3,'盛长柏');
#2.不可以为null的列必须插入值,可以为null的列插入值方式
方式一:
insert  into `boys`(`id`,`boyname`,`userCP`) values 
(1,'顾廷烨',0),
(2,'盛紘',NULL);
方式二:
insert  into `boys`(`id`,`boyname`) values 
(1,'顾廷烨'),
(2,'盛紘');
#3.插入子查询语句
INSERT INTO zhuanye (SELECT DISTINCT `专业代码`,`专业` FROM students ORDER BY `专业代码`);
#插入记录方式二:
insert  into `roles`
set `id`=1,`rolename`='盛名兰',`userCP`='2';

2、修改语句

/*UPDATE语句语法*/
#单表的MySQL UPDATE语句:
UPDATE [LOW_PRIORITY] [IGNORE] tbl_name
SET col_name1=expr1 [, col_name2=expr2 ...]  
[WHERE where_definition]
[ORDER BY ...]
[LIMIT row_count]
多表的UPDATE语句:
UPDATE [LOW_PRIORITY] [IGNORE] table_references
SET col_name1=expr1 [, col_name2=expr2 ...]
[WHERE where_definition]
/*UPDATE语法可以用新值更新原有表行中的各列。SET子句指示要修改哪些列和要给予哪些值。WHERE子句指定应更新哪些行。如果没有WHERE子句,则更新所有的行。如果指定了ORDER BY子句,则按照被指定的顺序对行进行更新。LIMIT子句用于给定一个限值,限制可以被更新的行的数目。*/
#示例:
UPDATE zhuanye SET zhuanye.`from_date`= 2000;       #修改默认值
UPDATE zhuanye SET zhuanye.`from_date`= 2002  WHERE zy_id LIKE '560%';
UPDATE zhuanye SET zhuanye.`from_date`= 2010  WHERE zy_id LIKE '6_0%';
UPDATE zhuanye SET zhuanye.`from_date`= 2012 WHERE zy_id = 520504;
#修改专业为‘临时’
ALTER TABLE book CHANGE COLUMN publishdate pubDate DATETIME;
UPDATE students SET students.`专业` = '临时';
#根据专业代码批量修改专业名
UPDATE students s
INNER JOIN zhuanye AS z
ON s.`专业代码` = z.`zy_id`
SET s.`专业` =z.`zy_name`;
#修改学生表中身份证号少一位X的信息(多表连接)
1.语句1:
UPDATE hnjd.`students` hs
INNER JOIN hnjd.`students` hstu
ON hs.`身份证号`=hstu.`身份证号` AND LENGTH(hs.`身份证号`)=17
SET hs.`身份证号`=CONCAT(hstu.`身份证号`,'X');
2.语句2:
UPDATE hnjd.`students` hs
INNER JOIN hnjd.`students` hstu
ON hs.`身份证号`=hstu.`身份证号` 
SET hs.`身份证号`=CONCAT(hstu.`身份证号`,'X')
WHERE LENGTH(hs.`身份证号`)=17;
#去掉身份证号的'X'
UPDATE hnjd.`students` hs
SET hs.`身份证号`=SUBSTR(hs.`身份证号`,1,17)
WHERE hs.`身份证号` LIKE '%X';
#身份证号末尾加'X'
UPDATE hnjd.`students`hs
SET hs.`身份证号`=CONCAT(hs.`身份证号`,'X')
WHERE LENGTH(hs.`身份证号`)=17;
#修改学院信息
UPDATE hnjd.`students` hs
INNER JOIN hnjd.`minzu` hm
ON hs.`民族` = hm.`民族`
SET hs.`民族`=hm.`代码`;
#
UPDATE zhuanye z
INNER JOIN students s
ON s.`专业代码`=z.`zy_id`
SET z.`学制`= s.`学制`,z.`层次`=s.`层次`,z.`学习形式`=s.`学习形式`;
SELECT * FROM zhuanye;

3、删除语句

#单表删除语法
delete  from 表名
where 筛选条件
order by 
limit 
#多表删除语法
1. SQL92语法:
delete 表1的别名,表2的别名
from 表1 别名,表2 别名
where 连接条件
and 筛选条件
order by 
limit 
2. SQL99语法:
delete 表1的别名,表2的别名
from 表1 别名
inner|left|right join 表2 别名
on 连接条件
where 筛选条件
order by 
limit 
DELETE FROM students 
WHERE students.`考生号` IN 
(SELECT temptab.`考生号` FROM temptab);

四、DDL语言的学习

DDL 数据定义语言

对库和表的管理:创建、修改、删除

#语句
创建: create
修改: alter
删除: drop

1、库的管理

1.创建数据库
CREATE DATABASE books;
CREATE DATABASE IF NOT EXISTS books; #为了防止系统报错添加if not exists 判断条件
2.修改数据库
#不能修改库名,可以修改字符集集
ALTER DATABASE `books` CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; 
3.删除数据库
DROP DATABASE books; 
DROP DATABASE IF EXISTS books;  #为了防止系统报错添加 if exists判断条件

2、表的管理

1.表的创建
/*语法
create table 表名(
            列名 列的类型[(长度) 约束],
            列名 列的类型[(长度) 约束],
            列名 列的类型[(长度) 约束],
            ....
            列名 列的类型[(长度) 约束],
 )
*/
#案例:创建表book
CREATE TABLE IF NOT EXISTS book(
                id INT,#编号
            bookname VARCHAR(20),#图书名
            price DOUBLE,#价格
            authorID INT,#作者编号
            publishDate DATETIME#出版日期

);
CREATE TABLE IF NOT EXISTS author(
        id INT,
        author_name VARCHAR(20),
        nation VARCHAR(10)
);
2.表的修改
/*
alter table 表名 add|drop|modify|change column 列名 【列类型 约束】;
*/
#①修改列名
alter table book change column pulishdate pubDate datetime;
ALTER TABLE `hnjd`.`zhuanye` CHANGE COLUMN `专业代码` `zhuaye_id` INT(11) NOT NULL; 
ALTER TABLE zhuanye CHANGE COLUMN `专业` `zhuanye_name` VARCHAR(20);
#②修改列的类型或约束
alter table book modify column pubdate timestamp;
ALTER TABLE `students`.`xueyuan` CHANGE `id` `id` INT(11) NOT NULL, ADD PRIMARY KEY (`id`); 
#③添加新列
alter table author add column annual double;
#④删除列
alter table author drop column annual;
#⑤修改表名
alter table author rename to book_author;
3.表的删除
drop table book;
drop table if exists book;
show tables;
4.表的复制
#1.仅仅复制表的结构
create table copy like book;
#2.复制表的结构+数据
create table copy2 select * from author;
create table copy3 select id,author_name from author;
#3.仅仅复制某些字段(不含数据)
create table copy4
select id,au_name
from author
where 0;

4、数据类型

5、数据约束

五、TCL语言的学习



示例:

mysql>SELECT 姓名,学号,性别,民族,二级学院名,`出生日期` from students where 民族 <> '汉族' and 性别 = '女' and 出生日期 > '2000-01-01'; 
mysql>SELECT 姓名,学号,性别,民族,出生日期 from students where 民族 <> '汉族' and 民族 <> '回族';
mysql> SELECT 姓名,学号,性别,民族,出生日期 from students where 民族 <> '汉族' and 性别 like '女' and 民族 <> '回族';
mysql> SELECT 姓名,学号,性别,民族,出生日期 from students where 民族 <> '汉族' and 民族 <> '回族' and 出生日期 > '2000-01-01';
mysql> SELECT 姓名,学号,性别,民族,出生日期 from students where 民族 <> '汉族' and 民族 <> '回族' and 出生日期 > '1998-01-01' and 出生日期 < '2001-12-31';

创建表:

DROP TABLE IF EXISTS `huizu`;
CREATE TABLE `huizu`  (
  `身份证号` bigint(18) UNSIGNED NOT NULL,
  `考生号` bigint(14) NOT NULL,
  `学号` bigint(11) NOT NULL,
  `姓名` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `性别` char(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `出生日期` date NOT NULL,
  `民族` char(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `专业代码` int(11) NOT NULL,
  `专业` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `二级学院名` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `班级` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `层次` char(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `学制` int(1) NOT NULL,
  `学习形式` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `入学日期` date NOT NULL,
  `当前年级` int(11) NOT NULL,
  `学籍状态` char(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `预计毕业日期` date NOT NULL,
  PRIMARY KEY (`身份证号`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

创建表从原表:

create table xxgcxy as SELECT * from students ; //从原表复制结构及数据
create table xxg as SELECT * from students limit 1; //从原表复制结构及1条记录数据
truncate table xxgcxy;  //截断表
create table xxg as SELECT * from students limit 1; 

从其他表中插入数据:

//创建表
create table 身份证号少于18位 as SELECT * from students limit 0;
//插入数据从其他表
insert into 身份证号少于18位 SELECT * from students where length(身份证号) < 18;
//删除数据记录
delete from students where length(身份证号) < 18 ;

更新数据:

//更新数据-字符串字段中添加字符
update table01 set 身份证号=CONCAT(身份证号,'X')
//mysql向表中某字段后追加一段字符串:
update table_name set field=CONCAT(field,'str')
//mysql 向表中某字段前加字符串
update table_name set field=CONCAT('str',field)

练习

DROP TABLE IF EXISTS xueyuan;
CREATE TABLE `students`.`xueyuan` ( `xy_id` INT NOT NULL, `xy_name` VARCHAR(20) NOT NULL, PRIMARY KEY (`xy_id`) );
1、去除不可见字符

通过HEX( )函数查询出不可见字符串,
HEX( )函数:返回十六进制值的字符串表示形式。

SELECT
    hnjd.`中国各民族代码`.`民族`,
    HEX('土家族'),
  HEX(hnjd.`中国各民族代码`.`民族`)
FROM
  hnjd.`中国各民族代码`
WHERE hnjd.`中国各民族代码`.`代码` = 15; 
#不可见字符为“C2A0”,转换为十进制为“49824”
SELECT CAST(0xc2a0 AS UNSIGNED);
#使用replace函数和trim函数修改字段
UPDATE 
  hnjd.`中国各民族代码`
SET
  hnjd.`中国各民族代码`.`民族` = TRIM(REPLACE(hnjd.`中国各民族代码`.`民族`,CHAR('49824'),''));

2、去重删除重复数据

DROP TABLE test;
CREATE TABLE test(id INT NOT NULL PRIMARY KEY, DAY DATE NOT NULL);   
INSERT INTO test(id, DAY) VALUES(1, '2006-10-08');  
INSERT INTO test(id, DAY) VALUES(2, '2006-10-08');  
INSERT INTO test(id, DAY) VALUES(3, '2006-10-09');   
SELECT * FROM test;  

DROP TABLE to_delete;
CREATE TEMPORARY TABLE to_delete (DAY DATE NOT NULL, min_id INT NOT NULL);   
INSERT INTO to_delete(DAY, min_id)  
  SELECT DAY, MIN(id) FROM test GROUP BY DAY HAVING COUNT(*) > 1; 
SELECT * FROM to_delete;

DELETE FROM test  
  WHERE EXISTS(  
     SELECT * FROM to_delete
     WHERE to_delete.day = test.day AND to_delete.min_id <> test.id  
  );
SELECT * FROM test;

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,651评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,468评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,931评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,218评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,234评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,198评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,084评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,926评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,341评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,563评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,731评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,430评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,036评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,676评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,829评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,743评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,629评论 2 354

推荐阅读更多精彩内容