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语法规范,不区分大小写,建议关键字大写,表名小写
每条命令用;结尾
每条命令可以进行缩进换行
注释:单行注释#注释文字,或者--空格注释文字
多行注释:/*注释文字*/
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%";
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
mysqld --defaults-file=/etc/my.cnf --user=root
在虚拟机上挂起了系统,再次使用虚拟机系统的时候docker是开启着mysql的,防火墙也开放了3306端口,端口监听也正常
但是就是telnet不通3306端口。
解决方法:
重启linux,然后docker启动mysl就telnet通了
select 查询列表 ⑦
from 表1 别名 ①
连接类型 join 表2 ②
on 连接条件 ③
where 筛选 ④
group by 分组列表 ⑤
having 筛选 ⑥
order by排序列表 ⑧
limit 起始条目索引,条目数; ⑨
含义:又称多表查询,当查询的字段来自于多个表时,就会用到连接查询
笛卡尔乘积现象:表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实现连接条件和筛选条件的分离,可读性较高
*/
子查询
含义:
出现在其他语句中的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或0SELECT 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#existsSELECT 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` );