MySQL学习记录

MySQL语句

第一章 查询语言,DQL语言

一、基础查询

/*
语法

SELECT  查询列表  FROM  表名;

特点
1、查询列表可以是字段、常量、表达式、函数,也可以是多个
2、查询结果是一个虚拟表
*/

1、查询表中单个字段
SELECT last_name FROM employees;
2、查询表中多个字段
SELECT last_name,salary,email FROM employees;
3、查询表中所有字段
SELECT * FROM employees;
4、查询常量值

#注意:字符型和日期型常量值须用单引号引起来

SELECT 100;
SELECT 'john';
5、查询表达式
SELECT 100%98;
6、查询函数
SELECT VERSION();
7、起别名

/*
目的
①便于理解;
②若查询字段有重名时可用别名区分*/

#方式一:使用AS

SELECT 100%98 as 结果;
SELECT last_name AS 姓,first_name AS 名 FROM employees;

#方式二:使用空格

SELECT last_name 姓,first_name 名 FROM employees;

#案例:查询salary,显示结果为out_put

SELECT salary 'out put' FROM employees;
8、去重

#案例:查询员工表中涉及到的所有部门编号

SELECT DISTINCT department_id FROM employees;
9、+号的作用

/*
java中+号作用
①运算符:两个操作数都为数值型
②连接符:只要有一个操作数为字符串

mysql中+号的作用
①仅仅是运算符功能

select 数值+数值,直接运算
select 字符+数值,先试图将字符转换成数值,若转换成功,则继续运算;否则转换为0,再运算
select null+值,结果都为null

相关知识点
CONCAT(str1,str2,…),拼接字符

IFNULL(expr1,expr2),判断某字段或表达式是否为null,若是null,返回指定的值,否则返回原本的值

ISNULL(expr),判断某字段或表达式是否为null,若是null,则返回1,否则返回0
*/

#案例:查询员工名和姓连接成一个字段,并显示为姓名

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

#显示表的全部列,各列用逗号连接,列头显示out_put

SELECT
CONCAT(first_name,',',last_name,',',job_id,',',IFNULL(commission_pct,0)) 
as 'out_put'
FROM
employees;

#显示department表结构,并查询表

DESC departments;
SELECT * FROM departments;

二、条件查询

/*
语法

SELECT
查询列表
FROM
表名
WHERE
筛选条件;

分类
(1)按条件表达式筛选,> < = != <> >= <=
(2)按逻辑表达式筛选,用于连接条件表达式 && || !,and or not

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

(3)模糊查询
①LIKE:一般与通配符搭配使用,可以判断字符型或数值型

  % 任意多个字符,包含0个字符
  - 任意单个字符

②BETWEEN AND

 可以提高语句简洁度
 包含临界值,且临界值不可调换顺序

③IN

判断某个字段的值是否属于in列表中的某一项
使用更简洁,列表内的值类型须保持一致或兼容

④is NULL is not NULL

=或<>不能判断null值
is null 或者is not null:仅仅可以判断null值,可读性比较高
安全等于:<=>,可以判断null值又可以判断普通数值,可读性低

*/

1、按条件表达式筛选

#案例:查询工资>12000的员工信息

SELECT * FROM employees
WHERE salary > 12000;

#案例:查询部门编号不等于90号的员工名和部门编号

SELECT  last_name, department_id FROM
employees WHERE department_id != 90;
2、按逻辑表达式筛选

#案例:查询工资在10000到20000之间的员工名、工资及奖金

SELECT  last_name, salary, commission_pct
FROM  employees WHERE
salary >= 10000 && salary <= 20000;

#案例:查询部门编号不是在90到110之间,或者工资高于15000的员工信息

SELECT * FROM employees 
WHERE
#department_id<90 OR department_id>110 OR salary>15000;
NOT(department_id>=90 AND department_id<=110) OR salary>15000;

三、模糊查询

#案例:查询员工名中包含字符a的员工信息

SELECT * FROM employees
WHERE last_name LIKE '%a%';

#案例:查询员工名第四个字符a,第七个字符为a的员工信息

SELECT * FROM employees
WHERE last_name LIKE '___a__a%';

#案例:查询员工名中第二个字符为_的员工名

SELECT last_name FROM employees 
WHERE 
#last_name LIKE '_\_%';
last_name LIKE '_$_%' ESCAPE '$';

#案例:查询员工编号在100到120之间的员工信息

SELECT * FROM employees
WHERE
#employee_id >= 100 AND employee_id <= 120;
employee_id BETWEEN 100 AND 120;

#案例:查询员工的工种编号是 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';
job_id in ('IT_PROG','AD_VP','AD_PRES');

#案例:查询没有|有奖金的员工名和奖金率

SELECT last_name, commission_pct FROM employees
WHERE
#commission_pct IS NULL;
commission_pct <=> NULL;
#commission_pct IS NOT NULL;

#案例:查询工资为12000的员工信息

SELECT last_name, salary FROM employees
WHERE salary <=> 12000;

#查询员工号为176的员工姓名和部门编号、年薪

SELECT last_name, department_id,
salary*12*(1+IFNULL(commission_pct,0)) as 年薪
FROM employees
WHERE employee_id = 176;

#选择工资不在5000到12000的员工姓名和工资

SELECT last_name, salary FROM employees
WHERE
NOT ( salary BETWEEN 5000 AND 12000 );

四、排序查询

/*
语法

select 查询列表
from 表名
【where 筛选条件】
ORDER BY 排序列表 【ASC | DESC】

特点

1、ASC:代表升序,默认,可以不写
   DESC:代表降序
2、ORDER BY子句中可以支持单个字段、多个字段、表达式、函数、别名
3、ORDER BY子句一般放在查询语句的最后面,LIMIT子句除外

*/

#案例:查询员工信息,要求工资从高到低排序

SELECT * FROM employees ORDER BY salary DESC;

#案例:查询员工信息,要求工资从低到高排序

#SELECT * FROM employees ORDER BY salary ASC;
SELECT * FROM employees ORDER BY salary;

#案例:查询部门编号>=90的员工信息,按入职时间的先后排序(添加筛选条件)

SELECT * FROM employees
WHERE department_id >= 90
ORDER BY hiredate;

#案例:按年薪的高低显示员工信息和年薪(按表达式排序)

SELECT *,salary*12*(1+IFNULL(commission_pct,0)) as 年薪
FROM employees
ORDER BY salary*12*(1+IFNULL(commission_pct,0)) DESC;

#案例:按年薪的高低显示员工信息和年薪(按别名排序)

SELECT *,salary*12*(1+IFNULL(commission_pct,0)) as 年薪
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中的方法,将一组逻辑语句封装在方法体中,对外暴露方法名
好处
①隐藏实现细节;
②提高代码的重用性
调用

SELECT 函数名(实参列表) 【from 表名】

特点
①函数名:叫什么
②函数功能:干什么

分类
1、单行函数:字符函数、数学函数、日期函数、其他函数、流程控制函数

CONCAT(str1,str2,...)
LENGTH(str)
IFNULL(expr1,expr2)等

2、分组函数:做统计使用,又称统计函数、聚合函数、组函数

sum函数、avg平均值、max最大值、min最小值、count计算个数

*/

1、单行函数
(1)字符函数
①LENGTH

#LENGTH(str)
#用于获取参数值的字节个数

SELECT LENGTH('john');
SELECT LENGTH('张三丰hahaha');

#查看mysql的系统参数

SHOW VARIABLES LIKE '%char%';
②CONCAT

#CONCAT(str1,str2,…)
#拼接字符

SELECT CONCAT(last_name,'_',first_name) 姓名 FROM employees;
③UPPER|LOWER

#大写:UPPER(str)
#小写:LOWER(str)

SELECT UPPER('john');
SELECT LOWER('JOHN');

#案例:将姓变大写,名变小写,然后拼接显示

SELECT CONCAT(UPPER(last_name),'_',LOWER(first_name)) 姓名 FROM employees;
④SUBSTR|SUBSTRING

/*SUBSTR(str,pos,len)
SUBSTRING(str FROM pos FOR len),截取子串
注意,索引从1开始
截取从’指定索引’处后面所有字符
*/

SELECT SUBSTR('数据库和数据管理系统',5) out_put;

#截取从’指定索引’处’指定字符长度’的字符

SELECT SUBSTR('数据库和数据管理系统',1,3) out_put;

#案例:姓名首字母大写,其他字符小写,然后拼接显示

SELECT CONCAT(UPPER(SUBSTR(last_name,1,1)),
SUBSTR(last_name,2),'_',first_name) 姓名 FROM employees;

SELECT CONCAT(UPPER(SUBSTR(last_name,1,1)),
'_',LOWER(SUBSTR(last_name,2))) out_put FROM employees;
⑤INSTR

#INSTR(str,substr)
#返回子串第一次出现的索引,若无则返回0

SELECT INSTR('数据库和数据管理系统','数据管理系统') AS out_put;
SELECT INSTR('数据库和数据管理系统','数管理系统') AS out_put;
⑥TRIM

/*
使用形式:

TRIM([remstr FROM] str)
TRIM([{BOTH | LEADING | TRAILING} [remstr] FROM] str)

过滤指定的字符串,返回字符串 str,其中所有remstr前缀和/或后缀都已被删除
分类符BOTH、LEADIN-首字符或TRAILING-尾字符中没有一个是给定的,则默认为BOTH
remstr为可选项,在未指定情况下,可删除空格
*/

SELECT TRIM('        数据库      ') AS out_put;
SELECT LENGTH(TRIM('        数据库      ')) AS out_put;
SELECT TRIM('ha'from 'hahah数ha据ha库hhaha') AS out_put;
⑦LPAD

#LPAD(str,len,padstr)
#用指定字符实现左填充指定长度

SELECT LPAD('数据库',5,'^') out_put;
SELECT LPAD('数据库',2,'^') out_put;
⑧RPAD

#RPAD(str,len,padstr)
#用指定字符实现左填充指定长度

SELECT rpad('数据库',5,'^') out_put;
SELECT rpad('数据库',2,'^') out_put;
⑨REPLACE

#REPLACE(str,from_str,to_str),替换

SELECT REPLACE('hahah数ha据ha库hhaha','ha','√') out_put;
(2)数学函数
①ROUND

#ROUND(X,D),四舍五入,
#D为保留几位小数,不输默认保留到整数

SELECT ROUND(-1.764,2) out_put;
②CEIL

#CEIL(X),向上取整
#返回>=该参数的最小整数

SELECT CEIL(-1.02) out_put;
SELECT CEIL(1.02) out_put;
③FLOOR

#FLOOR(X),向下取整
#返回<=该参数的最小整数

SELECT FLOOR(-1.02) out_put;
SELECT FLOOR(1.02) out_put;
④TRUNCATE

#TRUNCATE(X,D),截断
#截断到小数点后指定的第D个数

SELECT TRUNCATE(1.56789,4) out_put;
⑤MOD

/*
MOD(N,M),取余

MOD(N,M):N-N/M*M
MOD(N,M) 等价于 N%M

*/

SELECT MOD(10,-3) out_put; #10-10/(-3)*(-3)=10-(-3)*(-3)=10-9=1
SELECT -10%-3 out_put;     #(-10)-(-10)/(-3)*(-3)=(-10)-(3)*(-3)=(-10)-(-9)=-1
SELECT MOD(-10,3) out_put; #(-10)-(-10)/3*3=(-10)-(-3)*3=(-10)-(-9)=-1
⑥RAND

#RAND,获取随机数,返回0-1之间的小数

SELECT RAND();
(3)日期函数
①NOW()

#NOW(),返回当前日期及时间

SELECT NOW() DATE_TIME;
②CURDATE()

#CURDATE(),返回当前日期

SELECT CURDATE() DATE;
③CURTIME()

#CURTIME(),返回当前时间

SELECT CURTIME() TIME;
④获取日期时间的指定部分,年月日时分秒
SELECT YEAR(NOW()) 年;
SELECT YEAR('1993-10-12') 年;
SELECT YEAR('1993/10/12') 年;
SELECT YEAR(hiredate) 年 FROM employees;
SELECT MONTH(NOW()) 月;
SELECT MONTHNAME(NOW()) 月份;#以英文形式返回月份
SELECT DAY(NOW()) 日;
SELECT HOUR(NOW()) 时;
SELECT MINUTE(NOW()) 分;
SELECT SECOND(NOW()) 秒;
⑤STR_TO_DATE

/*
STR_TO_DATE(str,format)
将日期格式的字符转换成指定格式的日期

① %Y 四位的年份
② %y 两位的年份
③ %m 月份(01,02,…,11,12)
④ %c 月份(1,2,…,11,12)
⑤ %d 日(01,02,…,28,29,30,31)
⑥ %H 小时(24小时制)
⑦ %h 小时(12小时制)
⑧ %i 分钟(00,01,…,59)
⑨ %s 秒(00,01,…,59)
*/

SELECT STR_TO_DATE('1993-10-12','%Y-%m-%d') out_put;
SELECT STR_TO_DATE('95-2-26','%y-%c-%d') 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');
⑥DATE_FORMAT

#DATE_FORMAT(date,format):将日期转换成字符

SELECT DATE_FORMAT(NOW(),'%y年%m月%d日') out_put;

#案例:查询有奖金的员工名和入职日期(xx月/xx日 xx年)

SELECT
last_name 姓名,
DATE_FORMAT( hiredate, '%m月/%d日 %y年' ) 入职日期
FROM employees
WHERE commission_pct IS NOT NULL;
⑦ DATEDIFF

#DATEDIFF(expr1,expr2),返回两个日期相差的天数

SELECT DATEDIFF('1993-10-12','1995-02-26');
(4)其他函数
SELECT VERSION();   #查看当前软件版本
SELECT DATABASE();  #查看当前数据库
SELECT USER();      #查看当前用户
SELECT PASSWORD('数据库');#返回该字符的面形式
SELECT MD5('数据库');#返回该字符的面形式
(5)流程控制函数
①IF

#IF(expr1,expr2,expr3)
#若expr1为真,返回expr2,否则返回expr3

SELECT IF(10>5,'大','小') out_put;

SELECT
last_name 姓名,
commission_pct 奖金,
IF (commission_pct IS NULL,'没有奖金 嘤嘤','有奖金耶 嘻嘻') 有无奖金
FROM employees;
②CASE函数,使用一,switch case效果

/*
java中:

switch(变量表达式){
case 常量1:
语句1;
break;
default:
语句n;
break;
}

mysql中:

case 要判断的字段或表达式
when 常量1 then 要显示的值1或语句1;
when 常量2 then 要显示的值2或语句2;
...
else 要显示的值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 ORDER BY 新工资;
③CASE函数,使用二,类似多重if

/*
java中:

if(条件1){
语句1;
}
else if(条件2){
语句2;
}
else{
语句n;
}

mysql中:

case
when 条件1 then 要显示的值1或语句1
when 条件2 then 要显示的值2或语句2
...
else 要显示的值n或语句n
end

*/
/*案例:查询员工的工作情况:
若工资>20000,显示A级别
若工资>15000,显示B级别
若工资>10000,显示C级别
否则,显示D级别
*/

SELECT last_name 姓名,salary 工资,
CASE
WHEN salary>20000 then 'A级别'
WHEN salary>15000 then 'B级别'
WHEN salary>10000 then 'C级别'
ELSE 'D级别'
end as 薪资级别
FROM employees;
2、分组函数

/*
分类
sum函数、avg平均值、max最大值、min最小值、count计算个数

特点
1、sum、avg一般用于处理数值型
max、min、count可以处理任何类型
2、以上分组函数均忽略null值
3、可以和distinct搭配实现去重的运算
4、count一般使用count(*)用作统计函数
5、和分组函数一同查询的字段要求是group by后的字段
*/

(1)分组函数简单使用
SELECT SUM(salary) 工资总和 FROM employees;
SELECT AVG(salary) 工资平均值 FROM employees;
SELECT MAX(salary) 工资最大值 FROM employees;
SELECT MIN(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(salary),AVG(salary)  FROM employees;

SELECT MAX(last_name),MIN(hiredate) ,
COUNT(commission_pct) FROM employees;
(3)是否忽略null值
SELECT
SUM(commission_pct) 总和,
AVG(commission_pct) 平均,
MAX(commission_pct ) 最大值,
MIN(commission_pct ) 最小值,
COUNT(commission_pct) 个数,
SUM(commission_pct)/35 '验证1',
SUM(commission_pct)/107 '验证2'
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),count(*),count(1),count('测试') FROM employees;

#案例:查询员工表中做大入职日期和最小入职日期时间的相差天数

SELECT DATEDIFF(MAX(hiredate),MIN(hiredate)) 差值 FROM employees;

#案例:查询部门编号为90的员工个数

SELECT COUNT(*) FROM employees WHERE department_id=90;
(6)知识点:GROUP BY

/*
可以使用GROUP BY将表中的数据分成若干组

SELECT COLUMN,group_function(COLUMN)
FROM TABLE
WHERE CONDITION
GROUP BY group_by_expression
ORDER BY COLUMN;

语法

select 分组函数,列(要求出现在group by的后面)
from 表
【where 筛选条件】
group by 分组字段
having 分组后的筛选
【order by 排序列表】

注意:和分组函数一同查询的字段,要求是roup by后出现的字段

特点

1、分组查询筛选条件分两类:

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

①分组函数做条件肯定是放在having子句中
②能用分组前筛选的,就优先考虑使用分组前筛选

2、group by子句支持:
单个字段分组
多个字段分组(多个字段用逗号隔开无顺序要求)
表达式或函数分组

3、也可以添加排序(排序放在整个分组查询的最后)
*/
#案例:查询每个部门的平均工资

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

#案例:查询每个工种的最高工资

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;
#②根据①的结果进行筛选,查询员工个数>2的部门
SELECT COUNT(*) 员工数, department_id 部门编号
FROM employees
GROUP BY department_id
HAVING COUNT(*)>2;
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值