mysql学习笔记

mysql配置文件

my.ini

port:端口号

datadir:文件保存目录

character:字符集

default-storage-enginc:数据库引擎,用于执行sql语句

。。。

mysql服务的启动与停止通过命令行方式启动

service mysql start启动服务

service mysql stop 关闭服务

service mysql status 查看状态

mysql登录与退出

mysql -h localhost -P 3306 -u root -p

h:IP地址

P:指的是端口号

u:用户名

p:密码

h,P,u后面有没有空格都行,p密码后面不能有空格

如果连接的是本机数据库而且端口号是3306可以省去前两项

exit:退出

mysql常见命令

show databases:显示所有数据库

use database 打开某个数据库

show tables查看某个数据库的表,只有打开了某个数据库之后才能用,或者直接show tables from database;

select database():查看自己目前在操作哪一个库

创建表create table 表名(列名 列类型,列名 列类型。。。。)

查看表结构 desc 表名;

查看mysql版本

进入mysql之后用select version();mysql方法

没进入mysql用mysql -version;dos方法

Dql语言数据查询语言select

查询列表可以是表中字段,常量值,表达式,函数

select 100 查询常量

查询表达式select 100*10

查询函数select version()

为字段起别名select 100*10 as 结果,好处是便于理解,区分字段重名

起别名方式二 select last_name 姓

如果别名含有特殊字符,建议给别名添加引号

查询结果是一个虚拟的表格

去重关键字distinct,select语句只能有一个去重关键字,一个select语句只能查找一个去重字段,不能有第二个字段

+号的作用仅仅为运算符

两个均为数值型则做加法运算

其中一个为字符型则试图将字符转换为数值继续做加法,转换不成功则将字符转换为0

只要一方为null结果肯定为null

concat是拼接关键字语法concat(a,b,c,。。。)null和任何字符拼接结果都是null。select concat(lastname,fristname)as 姓名

if null(lastname,0)判断lastname是不是null,如果是null则lastname=0

is null(lastname)判断某字段或者表达式是否为null是的话返回1不是的话返回0

select语法的顺序,先找表,再执行筛选条件,最后执行查询操作

筛选条件

条件运算符><,=,<>同效果!=,>=,<=

逻辑表达式and,or,not

not(num>=100 and num<=200)or salary>15000,编号不在100到200之内或者工资高于15000的

模糊查询:like,between and,not between and,in,is null,is not null;

name like ‘%a%’,%代表任意多个字符包含0个字符

name like‘__n_l’%,_代表一个通配符,代表一个字符

name like ‘_\_’:\是转义字符

id between 100 and 120:包含临界值

id in(1,2,3,5,6,8)用于判断某字段的值是否属于in列表中的某一项,in列表的值必须统一或者兼容

id is null 判断id是不是为null

id is not null 判断id不为空

=或者<>不能用于判断null值

安全等与<=>判断是否等与,也可以用于判断null值i,也可以用于判断普通值i d <=>null

排序查询

order by 字句

select * from employees order by salary desc/asc

asc 升序默认

desc降序

order by支持别名

order by 可以根据多种字段进行排序 order by salary asc employee_id desc先根据工资进行生序排序,再根据员工id进行降序排序

order by 后面可以放单个字段,多个字段,表达式,函数,别名

order by 字句一般放在语句的最后,除了limit

执行顺序,from,where,select,order by

常见函数

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

调用 select 函数名(实参列表) from 表,如果实参列表中的参数是某张表的字段则加from 字句

单行函数

做处理使用的

字符函数

length获取参数值所占字节

concat拼接字符

upper,lower

select concat(upper(last_name),lower(first_name)) from employees

substr ,substring,:截取字符 ,sql语言中索引从1开始

2个参数,截取索引处以后字符

3个参数,截取索引处多少个字符

instr 返回子串第一次出现的索引,如果找不到返回0

trim 去前后空格

可以加参数 trim(“a” from"aaaalalalaaaaa")去前后的a

lpad、rpad:左/右填充

lpad(“丽丽”,2,“*”):用指定字符填充指定长度

replace 替换

replace(“丽丽乌瑞恩”,“乌瑞恩”,“语风”)用语风代替乌瑞恩

数学函数

round 四舍五入

算法就是绝对值取四舍五入然后添加正负号

ceil向上取整,返回>=该参数的最小整数

floor向下取整,返回<=该参数的最大整数

truncate 截断

truncate(1.69999,1) 1.6

mod 取余

日期函数

now 返回当前系统日期,日期+时间

curdate 返回系统当前日期不包含时间

curtime返回当前时间不包含日期

year(now())当前年

month(now())当前月

str_to_date:将日期格式字符转换为指定格式日期

str_to_date('1998-3-2','%Y-%c-%d')

date_format()将日期转换为字符

select date_format(hiredate,'%m/%d')

datediff(日期一,日期二)结果是日期一-日期二的天数

其他函数

version()版本号

database()查找当前库

user()查看当前用户

流程控制函数

if函数:类似于三目运算

select if(10>5,'big','small')

case函数,类似于java的switch case,做的是等值判断

select salary 原始工资,id,case id【case后面加判断条件】 when 30 then salary*1.1 when 40 then salary*1.2 else salary end 【case语句作为一个新列必须取别名】as 新工资 from employee

case 函数使用2类似于多重if,做的是区间判断

select salary,case when salary>20000 then 'A' else 'D' end 【case语句作为一个新列必须取别名】as 工资级别

分组函数

做统计使用的,又称为统计函数,聚合函数,组函数

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

参数类型支持哪些类型

sum,avg一般用于处理数值型

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

是否忽略null

以上分组函数都忽略了null

是否可以和distinct搭配

sum(distinct(salary))

以上所有分组函数都可以和distinct搭配

count

count(*)统计个数,表中多少数据只要有一个值不为null则+1

count(常量值)相当于在表中增加了一列常量值然后统计行数

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

分组查询

select 分组函数,列(要求出现在group by 的后面)

分组查询比较特殊,要求是分组函数和group by 后出现的字段

简单的分组查询

select max(salary),jobid from employees group by jobid

添加分组后的筛选 having,

select count(*),departmentid from employees group by departmentid having count(*)>2

分组函数条件肯定放在having之后

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

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

分组前筛选

筛选的对象是原始表,用where

分组后筛选

筛选的条件是分组后的结果集,用having

按多个字段进行分组

group by后面可以放多个字段,多个字段之间用,隔开,没有顺序

Dml语言数据操作语言insert,delete,update

DDl语言数据定义语言库和表的定义

TCL事务控制语言

tips

mysql语法规范,不区分大小写,建议关键字大写,表名小写

每条命令用;结尾

每条命令可以进行缩进换行

注释:单行注释#注释文字,或者--空格注释文字

多行注释:/*注释文字*/

mysql乱码问题解决

1.修改配置文件,配置文件的位置

通常在linux环境下my.cnf文件位于/etc/mysql/my.cnf/etc/my.cnf路径下

[client]
default-character-set=utf8

[mysql]
default-character-set=utf8

[mysqld]
init_connect='SET collation connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake

2.然后查询字符集

show variables like '%character%';

  show variables like "%colla%";

mysql学习笔记_第1张图片

3.修改datasource.url

 在uri后面加?useUnicode=true&characterEncoding=UTF-8

spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://192.168.1.131:3306/jdbc?useUnicode=true&characterEncoding=UTF-8
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

 

修改mysql启动时加载的配置文件

mysqld --defaults-file=/etc/my.cnf --user=root

linux中mysql出现异常 

在虚拟机上挂起了系统,再次使用虚拟机系统的时候docker是开启着mysql的,防火墙也开放了3306端口,端口监听也正常

但是就是telnet不通3306端口。

解决方法:

重启linux,然后docker启动mysl就telnet通了

Mysql子句执行顺序

select 查询列表    ⑦
from 表1 别名       ①
连接类型 join 表2   ②
on 连接条件         ③
where 筛选          ④
group by 分组列表   ⑤
having 筛选         ⑥
order by排序列表    ⑧
limit 起始条目索引,条目数;  ⑨

mysql连接查询

含义:又称多表查询,当查询的字段来自于多个表时,就会用到连接查询

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

发生原因:没有有效的连接条件
如何避免:添加有效的连接条件

分类:

    按年代分类:
    sql92标准:仅仅支持内连接
    sql99标准【推荐】:支持内连接+外连接(左外和右外)+交叉连接
    
    按功能分类:
        内连接:
            等值连接
            非等值连接
            自连接
        外连接:
            左外连接
            右外连接
            全外连接
            交叉连接

 

SELECT * FROM beauty;

SELECT * FROM boys;


SELECT NAME,boyName FROM boys,beauty
WHERE beauty.boyfriend_id= boys.id;

#一、sql92标准
#1、等值连接

① 多表等值连接的结果为多表的交集部分
②n表连接,至少需要n-1个连接条件
③ 多表的顺序没有要求
④一般需要为表起别名
⑤可以搭配前面介绍的所有子句使用,比如排序、分组、筛选

#案例1:查询女神名和对应的男神名

SELECT NAME,boyName 
FROM boys,beauty
WHERE beauty.boyfriend_id= boys.id;

#案例2:查询员工名和对应的部门名

SELECT last_name,department_name
FROM employees,departments
WHERE employees.`department_id`=departments.`department_id`;

#2、为表起别名
①提高语句的简洁度
②区分多个重名的字段

注意:如果为表起了别名,则查询的字段就不能使用原来的表名去限定
#查询员工名、工种号、工种名

SELECT e.last_name,e.job_id,j.job_title
FROM employees  e,jobs j
WHERE e.`job_id`=j.`job_id`;

#3、可以加筛选


#案例:查询有奖金的员工名、部门名

SELECT last_name,department_name,commission_pct

FROM employees e,departments d
WHERE e.`department_id`=d.`department_id`
AND e.`commission_pct` IS NOT NULL;

#案例2:查询城市名中第二个字符为o的部门名和城市名

SELECT department_name,city
FROM departments d,locations l
WHERE d.`location_id` = l.`location_id`
AND city LIKE '_o%';

#4、可以加分组


#案例1:查询每个城市的部门个数

SELECT COUNT(*) 个数,city
FROM departments d,locations l
WHERE d.`location_id`=l.`location_id`
GROUP BY city;


#案例2:查询有奖金的每个部门的部门名和部门的领导编号和该部门的最低工资

SELECT department_name,d.`manager_id`,MIN(salary)
FROM departments d,employees e
WHERE d.`department_id`=e.`department_id`
AND commission_pct IS NOT NULL
GROUP BY department_name,d.`manager_id`;


#5、可以加排序


#案例:查询每个工种的工种名和员工的个数,并且按员工个数降序

SELECT job_title,COUNT(*)
FROM employees e,jobs j
WHERE e.`job_id`=j.`job_id`
GROUP BY job_title
ORDER BY COUNT(*) DESC;


#6、可以实现三表连接?

#案例:查询员工名、部门名和所在的城市

SELECT last_name,department_name,city
FROM employees e,departments d,locations l
WHERE e.`department_id`=d.`department_id`
AND d.`location_id`=l.`location_id`
AND city LIKE 's%'

ORDER BY department_name DESC;

#7、非等值连接


#案例1:查询员工的工资和工资级别

SELECT salary,grade_level
FROM employees e,job_grades g
WHERE salary BETWEEN g.`lowest_sal` AND g.`highest_sal`
AND g.`grade_level`='A';

 


#8、自连接

#案例:查询 员工名和上级的名称

SELECT e.employee_id,e.last_name,m.employee_id,m.last_name
FROM employees e,employees m
WHERE e.`manager_id`=m.`employee_id`;

#二、sql99语法


语法:
    select 查询列表
    from 表1 别名 【连接类型】
    join 表2 别名 
    on 连接条件
    【where 筛选条件】
    【group by 分组】
    【having 筛选条件】
    【order by 排序列表】
    

分类:
内连接(★):inner
外连接
    左外(★):left 【outer】
    右外(★):right 【outer】
    全外:full【outer】
交叉连接:cross
#一)内连接
语法:

select 查询列表
from 表1 别名
inner join 表2 别名
on 连接条件;

分类:
等值
非等值
自连接

特点:
①添加排序、分组、筛选
②inner可以省略
③ 筛选条件放在where后面,连接条件放在on后面,提高分离性,便于阅读
④inner join连接和sql92语法中的等值连接效果是一样的,都是查询多表的交集


#1、等值连接
#案例1.查询员工名、部门名

SELECT last_name,department_name
FROM departments d
 JOIN  employees e
ON e.`department_id` = d.`department_id`;

#案例2.查询名字中包含e的员工名和工种名(添加筛选)

SELECT last_name,job_title
FROM employees e
INNER JOIN jobs j
ON e.`job_id`=  j.`job_id`
WHERE e.`last_name` LIKE '%e%';

#3. 查询部门个数>3的城市名和部门个数,(添加分组+筛选)

#①查询每个城市的部门个数
#②在①结果上筛选满足条件的

SELECT city,COUNT(*) 部门个数
FROM departments d
INNER JOIN locations l
ON d.`location_id`=l.`location_id`
GROUP BY city
HAVING COUNT(*)>3;


#案例4.查询哪个部门的员工个数>3的部门名和员工个数,并按个数降序(添加排序)

#①查询每个部门的员工个数

SELECT COUNT(*),department_name
FROM employees e
INNER JOIN departments d
ON e.`department_id`=d.`department_id`
GROUP BY department_name

#② 在①结果上筛选员工个数>3的记录,并排序

SELECT COUNT(*) 个数,department_name
FROM employees e
INNER JOIN departments d
ON e.`department_id`=d.`department_id`
GROUP BY department_name
HAVING COUNT(*)>3
ORDER BY COUNT(*) DESC;

#5.查询员工名、部门名、工种名,并按部门名降序(添加三表连接)

SELECT last_name,department_name,job_title
FROM employees e
INNER JOIN departments d ON e.`department_id`=d.`department_id`
INNER JOIN jobs j ON e.`job_id` = j.`job_id`

ORDER BY department_name DESC;

#2)非等值连接

#查询员工的工资级别

SELECT salary,grade_level
FROM employees e
 JOIN job_grades g
 ON e.`salary` BETWEEN g.`lowest_sal` AND g.`highest_sal`;


 
 
 #查询工资级别的个数>20的个数,并且按工资级别降序

 SELECT COUNT(*),grade_level
FROM employees e
 JOIN job_grades g
 ON e.`salary` BETWEEN g.`lowest_sal` AND g.`highest_sal`
 GROUP BY grade_level
 HAVING COUNT(*)>20
 ORDER BY grade_level DESC;
 


 #3)自连接
 
 #查询员工的名字、上级的名字
 

SELECT e.last_name,m.last_name
 FROM employees e
 JOIN employees m
 ON e.`manager_id`= m.`employee_id`;


 
  #查询姓名中包含字符k的员工的名字、上级的名字
 

SELECT e.last_name,m.last_name
 FROM employees e
 JOIN employees m
 ON e.`manager_id`= m.`employee_id`
 WHERE e.`last_name` LIKE '%k%';


 
 
 #二、外连接
 
 /*
 应用场景:用于查询一个表中有,另一个表没有的记录
 
 特点:
 1、外连接的查询结果为主表中的所有记录
    如果从表中有和它匹配的,则显示匹配的值
    如果从表中没有和它匹配的,则显示null
    外连接查询结果=内连接结果+主表中有而从表没有的记录
 2、左外连接,left join左边的是主表
    右外连接,right join右边的是主表
 3、左外和右外交换两个表的顺序,可以实现同样的效果 
 4、全外连接=内连接的结果+表1中有但表2没有的+表2中有但表1没有的

 #左外连接

 SELECT b.*,bo.*
 FROM boys bo
 LEFT OUTER JOIN beauty b
 ON b.`boyfriend_id` = bo.`id`
 WHERE b.`id` IS NULL;

 #案例1:查询哪个部门没有员工
 #左外

 SELECT d.*,e.employee_id
 FROM departments d
 LEFT OUTER JOIN employees e
 ON d.`department_id` = e.`department_id`
 WHERE e.`employee_id` IS NULL;
 

 #右外

  SELECT d.*,e.employee_id
 FROM employees e
 RIGHT OUTER JOIN departments d
 ON d.`department_id` = e.`department_id`
 WHERE e.`employee_id` IS NULL;
 

 #全外

USE girls;
 SELECT b.*,bo.*
 FROM beauty b
 FULL OUTER JOIN boys bo
 ON b.`boyfriend_id` = bo.id;

 #交叉连接

 SELECT b.*,bo.*
 FROM beauty b
 CROSS JOIN boys bo;


 
 
 
 #sql92和 sql99pk
 /*
 功能:sql99支持的较多
 可读性:sql99实现连接条件和筛选条件的分离,可读性较高
 */

 mysql子查询


子查询
含义:
出现在其他语句中的select语句,称为子查询或内查询
外部的查询语句,称为主查询或外查询

分类:
按子查询出现的位置:
    select后面:
        仅仅支持标量子查询

    
    from后面:
        支持表子查询

    where或having后面:★
        标量子查询(单行) √
        列子查询  (多行) √   
        行子查询

        
    exists后面(相关子查询)
        表子查询


按结果集的行列数不同:
    标量子查询(结果集只有一行一列)
    列子查询(结果集只有一列多行)
    行子查询(结果集有一行多列)
    表子查询(结果集一般为多行多列)


#一、where或having后面
1、标量子查询(单行子查询)
2、列子查询(多行子查询)

3、行子查询(多列多行)

特点:
①子查询放在小括号内
②子查询一般放在条件的右侧
③标量子查询,一般搭配着单行操作符使用
> < >= <= = <>

列子查询,一般搭配着多行操作符使用
in、any/some、all

④子查询的执行优先于主查询执行,主查询的条件用到了子查询的结果


#1.标量子查询★

#案例1:谁的工资比 Abel 高?

#①查询Abel的工资

SELECT salary
FROM employees
WHERE last_name = 'Abel'

#②查询员工的信息,满足 salary>①结果

SELECT *
FROM employees
WHERE salary>(
    SELECT salary
    FROM employees
    WHERE last_name = 'Abel'
);

#案例2:返回job_id与141号员工相同,salary比143号员工多的员工 姓名,job_id 和工资

#①查询141号员工的job_id

SELECT job_id
FROM employees
WHERE employee_id = 141

#②查询143号员工的salary

SELECT salary
FROM employees
WHERE employee_id = 143

#③查询员工的姓名,job_id 和工资,要求job_id=①并且salary>②

SELECT last_name,job_id,salary
FROM employees
WHERE job_id = (
    SELECT job_id
    FROM employees
    WHERE employee_id = 141
) AND salary>(
    SELECT salary
    FROM employees
    WHERE employee_id = 143

);


#案例3:返回公司工资最少的员工的last_name,job_id和salary

#①查询公司的 最低工资

SELECT MIN(salary)
FROM employees

#②查询last_name,job_id和salary,要求salary=①

SELECT last_name,job_id,salary
FROM employees
WHERE salary=(
    SELECT MIN(salary)
    FROM employees
);


#案例4:查询最低工资大于50号部门最低工资的部门id和其最低工资

#①查询50号部门的最低工资

SELECT  MIN(salary)
FROM employees
WHERE department_id = 50

#②查询每个部门的最低工资

SELECT MIN(salary),department_id
FROM employees
GROUP BY department_id

#③ 在②基础上筛选,满足min(salary)>①

SELECT MIN(salary),department_id
FROM employees
GROUP BY department_id
HAVING MIN(salary)>(
    SELECT  MIN(salary)
    FROM employees
    WHERE department_id = 50
);

#非法使用标量子查询,子查询结果不是一行一列

SELECT MIN(salary),department_id
FROM employees
GROUP BY department_id
HAVING MIN(salary)>(
    SELECT  salary
    FROM employees
    WHERE department_id = 250
);

#2.列子查询(多行子查询)★
#案例1:返回location_id是1400或1700的部门中的所有员工姓名

#①查询location_id是1400或1700的部门编号

SELECT DISTINCT department_id
FROM departments
WHERE location_id IN(1400,1700)

#②查询员工姓名,要求部门号是①列表中的某一个

SELECT last_name
FROM employees
WHERE department_id  <>ALL(
    SELECT DISTINCT department_id
    FROM departments
    WHERE location_id IN(1400,1700)
);


#案例2:返回其它工种中比job_id为‘IT_PROG’工种任一工资低的员工的员工号、姓名、job_id 以及salary

#①查询job_id为‘IT_PROG’部门任一工资

SELECT DISTINCT salary
FROM employees
WHERE job_id = 'IT_PROG'

#②查询员工号、姓名、job_id 以及salary,salary<(①)的任意一个

SELECT last_name,employee_id,job_id,salary
FROM employees
WHERE salary'IT_PROG';

#或

SELECT last_name,employee_id,job_id,salary
FROM employees
WHERE salary<(
    SELECT MAX(salary)
    FROM employees
    WHERE job_id = 'IT_PROG'
) AND job_id<>'IT_PROG';

#案例3:返回其它部门中比job_id为‘IT_PROG’部门所有工资都低的员工   的员工号、姓名、job_id 以及salary

SELECT last_name,employee_id,job_id,salary
FROM employees
WHERE salary'IT_PROG';

#或

SELECT last_name,employee_id,job_id,salary
FROM employees
WHERE salary<(
    SELECT MIN( salary)
    FROM employees
    WHERE job_id = 'IT_PROG'
) AND job_id<>'IT_PROG';

#3、行子查询(结果集一行多列或多行多列)

#案例:查询员工编号最小并且工资最高的员工信息

SELECT * 
FROM employees
WHERE (employee_id,salary)=(
    SELECT MIN(employee_id),MAX(salary)
    FROM employees
);

#①查询最小的员工编号

SELECT MIN(employee_id)
FROM employees


#②查询最高工资

SELECT MAX(salary)
FROM employees


#③查询员工信息

SELECT *
FROM employees
WHERE employee_id=(
    SELECT MIN(employee_id)
    FROM employees


)AND salary=(
    SELECT MAX(salary)
    FROM employees

);


#二、select后面仅仅支持标量子查询
 

#案例:查询每个部门的员工个数

SELECT d.*,(

    SELECT COUNT(*)
    FROM employees e
    WHERE e.department_id = d.`department_id`
 ) 个数
 FROM departments d;

 #案例2:查询员工号=102的部门名
 

SELECT (
    SELECT department_name,e.department_id
    FROM departments d
    INNER JOIN employees e
    ON d.department_id=e.department_id
    WHERE e.employee_id=102
    
) 部门名;

#三、from后面将子查询结果充当一张表,要求必须起别名
#案例:查询每个部门的平均工资的工资等级
#①查询每个部门的平均工资

SELECT AVG(salary),department_id
FROM employees
GROUP BY department_id
SELECT * FROM job_grades;

#②连接①的结果集和job_grades表,筛选条件平均工资 between lowest_sal and highest_sal

SELECT  ag_dep.*,g.`grade_level`
FROM (
    SELECT AVG(salary) ag,department_id
    FROM employees
    GROUP BY department_id
) ag_dep
INNER JOIN job_grades g
ON ag_dep.ag BETWEEN lowest_sal AND highest_sal;

#四、exists后面(相关子查询)
语法:
exists(完整的查询语句)
结果:
1或0

SELECT EXISTS(SELECT employee_id FROM employees WHERE salary=300000);


#案例1:查询有员工的部门名

#in  #exists

SELECT department_name
FROM departments d
WHERE d.`department_id` IN(
    SELECT department_id
    FROM employees
)

SELECT department_name
FROM departments d
WHERE EXISTS(
    SELECT *
    FROM employees e
    WHERE d.`department_id`=e.`department_id`
);


#案例2:查询没有女朋友的男神信息
#in#exists



SELECT bo.*
FROM boys bo
WHERE bo.id NOT IN(
    SELECT boyfriend_id
    FROM beauty
)


SELECT bo.*
FROM boys bo
WHERE NOT EXISTS(
    SELECT boyfriend_id
    FROM beauty b
    WHERE bo.`id`=b.`boyfriend_id`

);

 

你可能感兴趣的:(mysql)