学习笔记:MYSQL查询

database

前言:之前花费两天晚上看了一遍Mysql必知必会,没想到后面效果太差。不如跟着网课视频敲一遍和完成练习题目(练习题没写注释就不记录了),再记下笔记。

一、基本的查询select语句

语法: select 查询列表 from 表名;

查询列表可以是表中的字段、常量值、表达式、函数,查询结果是一个虚拟的表格。

SELECT last_name FROM employees;

#2.查询表中的多个字段

SELECT first_name,last_name,phone_number,email FROM employees;

#3.查询表中的所有字段

SELECT * FROM employees;

#4.查询常量

SELECT 10;

#5.查询表达式

SELECT 1010*2;

#6.查询函数

SELECT VERSION( );

#7.起别名

SELECT salary AS `收入` FROM employees;

SELECT first_name `名` FROM employees;

#8.去重

SELECT DISTINCT salary AS `工资样本` FROM employees;

#9.‘+’加号:仅有运算符的作用,没有拼接字符的作用

SELECT 1010 + 2023;

#10.使用concat连接字段

SELECT CONCAT(first_name,last_name) FROM employees;

二、条件查询

语法:select 查询列表 from 表名

where 筛选条件;

分类:

1.按条件表达式筛选

运算符: > < = != <> >= <=

2.按逻辑表达式筛选

运算符: || && !

也可以使用 or and not

3.模糊查询

like

between and

in

is null

#按条件表达式查询

#1. 查询工资>12000的员工信息

SELECT * FROM employees WHERE salary >12000;

#2. 查询部门编号不等于90号的员工名和部门编号

SELECT last_name,department_id FROM employees WHERE department_id !=90;

#按逻辑表达式查询

#3.查询工资在10000~20000的员工名、工资、奖金

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

#4.查询部门编号不是在90~100,或者工资高于15000的员工信息

SELECT * FROM employees WHERE department_id <90 OR department_id >110 OR salary >15000;

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

#like查询

#5.查询员工名中有a字符的员工信息

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

#6.查询员工名中第三个字符为n,第五个字符为l的员工名和工资

SELECT last_name,salary FROM employees WHERE last_name LIKE "__n_l%";

#7.查询员工名第二个字符为_的员工信息

SELECT * FROM employees WHERE last_name LIKE "_\_%";

SELECT * FROM employees WHERE last_name LIKE "_$_%" ESCAPE "$";

#between and 两个临界值不能调换顺序

#8.查询员工编号在100~120的员工信息

SELECT * FROM employees WHERE employee_id BETWEEN 100 AND 120;

#in

#9.查询员工工种是 IT_PROG,AD_VP,AD_PRSE中的一个的员工名和工种

SELECT last_name, job_id FROM employees WHERE job_id IN("IT_PROG","AD_VP","AD_PRSE");

#is null

#10. 查询没有奖金的员工名和奖金率

SELECT last_name,commission_pct FROM employees WHERE commission_pct IS NULL;

#安全等于

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

#11. 查询有奖金的员工名和奖金率

SELECT last_name,commission_pct FROM employees WHERE commission_pct IS NOT NULL;

三、排序查询

语法:

select 查询列表 from 表名

where 筛选条件

order by 排序列表 ase | desc;

order by子句一般放在查询语句最后面,limit子句除外

order by子句支持单个字段、多个字段、表达式、别名、函数

#1.查询员工信息,要求按工资从低到高排序

SELECT * FROM employees

ORDER BY salary ASC;

#2.查询部门编号>90的员工信息,按入职时间的先后排序

SELECT * FROM employees

WHERE department_id >90

ORDER BY hiredate ASC;

#3.按年薪的高低显示员工的信息和年薪

SELECT * ,salary*12 AS "年薪" FROM employees

ORDER BY salary*12 ASC;

#4.按姓名的长度显示员工姓名和薪水

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

ORDER BY LENGTH(CONCAT(first_name,last_name)) ASC;

#5.查询员工信息,先按工资升序排序,再按员工编号降序排序

SELECT * FROM employees

ORDER BY salary ASC,employee_id DESC;

四、常见函数

语法:

select 函数名(实参列表)from 表名;

分类:

  1. 单行函数

    比如:concat、length、ifnull

  2. 分组函数

#(一)字符函数

#1.length 获取参数值的字节个数

SELECT LENGTH("中文");

SELECT LENGTH("English");

#2.concat 拼接字符串

SELECT CONCAT(first_name," ",last_name) FROM employees;

#3.upper、lower

#将姓大写、名小写,再拼接

SELECT CONCAT(UPPER(first_name)," ",LOWER(last_name)) AS "姓名" FROM employees;

#4.substr、substring 索引从一开始

SELECT SUBSTR("一二三四五",1,4);

#将名中的首字符大写,其余字符小写,再拼接起来

SELECT CONCAT(UPPER(SUBSTR(last_name,1,1)),"_",LOWER(SUBSTR(last_name,2))) FROM employees;

#5.instr 返回子串第一次出现的索引,没有则返回0

SELECT INSTR("五岳泰山","泰山");

#6.trim

SELECT TRIM(" 23232 ");

SELECT TRIM("o" FROM "oooo中文oooo");

#7. lpad 用指定的字符左填充到指定的长度

SELECT LPAD("中文",9,"*");

#8. Rpad 用指定的字符右填充到指定的长度

SELECT RPAD("英文",10,"o");

#9. replace 替换

SELECT REPLACE("中文****","*","o");

##(二)数学函数

#1.round 四舍五入

SELECT ROUND(1.4);

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

SELECT CEIL(1.4);

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

SELECT FLOOR(1.5);

#4.truncate 截断,保留几位小数

SELECT TRUNCATE(1.8888,0);

#5.mod 取余

SELECT MOD(34,8);

##(三)日期函数

#1.now 返回当前系统日期和时间

SELECT NOW();

#2.curdate 返回当前系统日期,不包括时间

SELECT CURDATE();

#3.curtime 返回时间,不包括日期

SELECT CURTIME()

#4.获取指定部分,年、月、日、小时、分钟、秒

SELECT YEAR(NOW());

SELECT MONTH(NOW());

SELECT MONTHNAME(NOW());

SELECT MINUTE(NOW());

#5.str_to_date 将字符通过指定的格式转换为日期

SELECT STR_TO_DATE("2021-4-13","%Y-%c-%d") out_put;

#查询入职日期是1992-4-3的员工

SELECT * FROM employees WHERE hiredate = STR_TO_DATE("4-3 1992","%c-%d %Y");

#date_format 将日期转换成字符

SELECT DATE_FORMAT(NOW(),"%Y年%c月%d日");

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

SELECT CONCAT(first_name," ",last_name),DATE_FORMAT(hiredate,"%Y年%c月%d日") 入职日期 FROM employees

WHERE commission_pct IS NOT NULL;

##(四)其它函数

#1.显示mysql的版本号

SELECT VERSION();

#2.显示当前打开的数据库

SELECT DATABASE();

#3.显示当前登录的用户

SELECT USER();

##(五)流程控制函数

#if if else的效果

SELECT IF(35>10,"大","小");

SELECT CONCAT(first_name," ",last_name),IF(commission_pct,"有奖金","没奖金") FROM employees;

#case 要判断的字符或表达式

#when 常量 then 要显示的值或语句

#when 常量 then 要显示的值或语句

#...

#else 要显示的值或语句

#end

#查询员工的工资,要求:

#部门编号为30,显示的工资为1.1倍

#部门编号为40,显示的工资为1.2倍

#部门编号为50,显示的工资为1.3倍

#其它部门,显示的工资为1倍

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

#when 条件1 then 要显示的值或表达式

#when 条件2 then 要显示的值或表达式

#when 条件3 then 要显示的值或表达式

#else 要显示的值或表达式

#end

#查询员工的工资情况

/*如果工资大于20000,显示等级A

如果工资大于15000,显示等级B

如果工资大于10000,显示等级C

否则显示等级D

*/

SELECT salary,

CASE salary

WHEN salary>20000 THEN "等级A"

WHEN salary>15000 THEN "等级B"

WHEN salary>10000 THEN "等级C"

ELSE "等级D"

END AS 工资等级

FROM employees;

#分组函数

/*功能:用作统计使用,又称为聚合函数、统计函数或组函数

分类:

sum 求和、avg 平均值、max 最大值、count 计算个数

*/

#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;

#2.支持哪些参数类型 sum、 avg一般用于处理数值型 max、min、count可以处理任何类型

SELECT SUM(last_name) FROM employees;

SELECT MAX(last_name) FROM employees;

SELECT COUNT(last_name) FROM employees;

#3.是否忽略null值 下面的分组函数都忽略null值

SELECT MAX(commission_pct),SUM(commission_pct),AVG(commission_pct) FROM employees;

SELECT COUNT(employee_id),COUNT(commission_pct) FROM employees;

#4.和distinct搭配使用

SELECT SUM(DISTINCT(salary)) FROM employees;

SELECT SUM(salary) FROM employees;

#5.count 函数的详细介绍

/*效率:

MYISAM引擎下,count(*)效率高

INNODB引擎下,count(*)和count(1)效率差不多,比count(字段)效率高

*/

SELECT COUNT(salary) FROM employees;

SELECT COUNT(*) FROM employees;

SELECT COUNT(1) FROM employees;

#6.和分组函数一同查询的字段的限制:要求是group by后面的字段

SELECT SUM(salary),employee_id FROM employees;

五、分组查询

语法:

select 分组函数、列(要求是出现在group by后面的字段)

from 表名

where 筛选条件

group by 分组的列表

order by 子句

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

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

分组前筛选 数据源是原始表 位置在group by前面 关键字是where

分组后筛选 分组后的结果集 在group by后面 having

分组函数作为筛选条件的,肯定放在having子句中。

group by子句支持单个字段分组、多个字段分组、表达式或函数,也可以添加排序

#分组查询

#1.查询每个工种的最高工资

SELECT MAX(salary),job_id FROM employees

GROUP BY job_id;

#2.查询每个位置上的部门个数

SELECT COUNT(*),location_id FROM departments

GROUP BY location_id;

#3.添加筛选条件:查询邮箱中包含a字符的,每个部门的平均工资

SELECT AVG(salary),department_id FROM employees

WHERE email LIKE "%a%"

GROUP BY department_id;

#4.查询有奖金的每个领导手下员工的最高工资

SELECT MAX(salary),manager_id FROM employees

WHERE commission_pct IS NOT NULL

GROUP BY manager_id;

#添加复杂的筛选条件

#5.查询哪个部门的员工个数>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;

#6.查询每个工种有奖金员工的最高工资>12000的工种编号和最高工资

SELECT MAX(salary),job_id FROM employees

GROUP BY job_id

HAVING MAX(salary) >12000;

#7.查询领导编号>102的每个领导手下的最低工资>5000的领导编号是哪个,以及其最低工资

SELECT manager_id,MIN(salary) FROM employees

WHERE manager_id >102

GROUP BY manager_id

HAVING MIN(salary) >5000;

#按表达式或函数分组

#8.按员工名字的长度,查询每一组员工个数,筛选员工个数>5的有哪些

SELECT COUNT(*),LENGTH(last_name) FROM employees

GROUP BY LENGTH(last_name)

HAVING COUNT(*) >5;

#按多个字段分组

#9.查询每个部门每个工种的员工的平均工资

SELECT AVG(salary),department_id,job_id FROM employees

GROUP BY department_id,job_id;

#添加排序

#10.查询每个部门每个工种的员工的平均工资,按平均工资的高低排序

SELECT AVG(salary),department_id,job_id FROM employees

GROUP BY department_id,job_id

HAVING AVG(salary) >10000

ORDER BY AVG(salary) ASC;

六、多表查询

按标准分类:

sql92:仅支持内连接, sql99

按功能分类:

内连接 自连接 外连接

sql99语法:

select 查询列表

from 表名 连接类型

join 表名

on 连接条件

where 筛选条件

group by 分组条件

having 筛选条件

order by 筛选条件

分类:

内连接: inner

外连接: 左外连接 left outer, 右外连接 right outer, 全外 full outer

交叉连接:cross join

(1)内连接:

语法:select 查询列表

from 表名

inner join 表名

on 连接条件

分类:等值连接 非等值连接 自连接

(2)外连接:

应用场景:用于查询一个表中有,另外一个表中没有的记录。

特点:

外连接的查询结果为主表中的所有记录,

如果从表中有与它匹配的,则显示匹配的值,

从表中没有与它匹配的,则显示null值

外连接查询结果=内连接结果+主表中有而从表中没有的记录

左外连接,left join左边的是主表

右外连接,right join右边的是主表

全外连接=内连接结果+主表中有而从表中没有的记录+从表中有而主表中没有的记录

##自连接

#一、内连接

#等值连接

#1.查询员工名、部门名

SELECT last_name,department_name

FROM employees e

INNER JOIN departments d

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 COUNT(*),city

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

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;

##非等值连接

#6.查询员工的工资级别

SELECT last_name,salary,grade_level FROM employees e

INNER JOIN job_grades j ON e.salary BETWEEN j.lowest_sal AND j.highest_sal;

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

SELECT COUNT(*),grade_level FROM employees e

INNER JOIN job_grades j ON e.salary BETWEEN j.lowest_sal AND j.highest_sal

GROUP BY j.grade_level

HAVING COUNT(*) >20

ORDER BY j.grade_level DESC;

##自连接

#8.查询员工的名字、上级的名字

SELECT e.last_name 员工名,m.last_name 上级 FROM employees e

INNER JOIN employees m ON e.manager_id = m.employee_id;

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

SELECT e.last_name 员工名,m.last_name 上级 FROM employees e

INNER JOIN employees m ON e.manager_id = m.employee_id

WHERE e.last_name LIKE "%k%";

#二、外连接

#左外连接

#1.查询没有男朋友的女神

SELECT be.name,b.boyname FROM beauty be

LEFT OUTER JOIN boys b ON be.boyfriend_id = b.id

WHERE b.id IS NULL;

#2.查询哪个部门没有员工

SELECT department_name,employee_id FROM departments d

LEFT OUTER JOIN employees e ON d.department_id = e.department_id;

WHERE d.department_id IS NULL;

#右外连接

SELECT department_name FROM employees e

RIGHT OUTER JOIN departments d ON d.department_id = e.department_id;

#全外 mysql中不支持

SELECT be.*,bo.* FROM beauty be

FULL OUTER JOIN boys bo ON be.boyfriend_id = bo.id;

#交叉连接

SELECT be.*,bo.* FROM beauty be

CROSS JOIN boys bo ;

七、子查询

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

外部的查询语句,称为主查询或外查询

分类:

按子查询出现的位置:

select 后面:仅支持标量子查询;

from后面: 支持表子查询;

where或having后面:标量子查询或列子查询、行子查询;

exist后面:相关子查询

按结果集的行列数不同划分:

标量子查询(结果集为一行一列)

行子查询(一行多列)

列子查询(一列多行)

表子查询(多行多列)

#一、where或having后面

/*

支持标量子查询或列子查询、行子查询

特点:

子查询一般放在括号内

子查询一般放在条件的右侧

标量子查询:一般搭配单行操作符使用(> < =)

列子查询:一般搭配着多行操作符使用(in any/some or)

*/

##标量子查询

#1.谁的工资比Abel高?

SELECT salary FROM employees

WHERE last_name = "Abel";

SELECT last_name,salary FROM employees

WHERE salary >(

SELECT salary FROM employees

WHERE last_name = "Abel");

#2.查询job_id 与141号员工相同,salary比143号多的员工姓名、job_id和工资

SELECT job_id FROM employees

WHERE employee_id = 141;

SELECT salary FROM employees

WHERE employee_id = 143;

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.返回工资最少的员工的姓名、job_id和salary

SELECT MIN(salary) FROM employees;

SELECT last_name,job_id,salary FROM employees

WHERE salary = (SELECT MIN(salary) FROM employees);

#having

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

SELECT MIN(salary),department_id FROM employees

GROUP BY department_id

HAVING department_id = 50;

SELECT MIN(salary),department_id FROM employees

GROUP BY department_id

HAVING MIN(salary) > (

SELECT MIN(salary) FROM employees

GROUP BY department_id

HAVING department_id = 50);

#行子查询

#5.查询员工编号最小且工资最高的员工信息

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 * FROM employees

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

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

#6.查询每个部门的员工个数

SELECT COUNT(*),department_name FROM departments d

LEFT OUTER JOIN employees e ON d.department_id = e.department_id

GROUP BY department_name;

SELECT d.*,(

SELECT COUNT(*) FROM employees e

WHERE e.department_id = d.department_id)

FROM departments d;

#7.查询员工号位为102的部门名

SELECT department_name FROM employees e

INNER JOIN departments d ON e.department_id = d.department_id

WHERE employee_id = 102;

#三、from后面:列子查询,将子查询的结果当做一张表,要求必须取别名

#8.查询每个部门的平均工资的工资等级

/* 可能错误 */

SELECT AVG(salary),department_id,grade_level FROM employees e

INNER JOIN job_grades ON salary BETWEEN lowest_sal AND highest_sal

GROUP BY department_id;

SELECT ag.*, grade_level

FROM (

SELECT AVG(salary) s,department_id FROM employees

GROUP BY department_id) ag

INNER JOIN job_grades ON ag.s BETWEEN lowest_sal AND highest_sal;

#四、exist后面

/*语法:

exist(完整的查询语句)

结果:1或0

*/

#9. 查询有员工的部门名

SELECT department_name FROM departments d

WHERE EXISTS(

SELECT * FROM employees e

WHERE e.department_id = d.department_id);

SELECT department_name FROM departments d

INNER JOIN employees e ON d.department_id = e.department_id;

八、分页查询

要显示的数据,一页显示不全,需要分页提交sql请求

语法:

select 查询列表

from 表名

inner join 表名 on 连接条件

where 筛选条件

group by 分组条件

having 分组后的筛选

order by 排序的字段

limit offset,size

offset 要显示条目的起始索引(起始索引从零开始)

size 要显示的条目数

注意:limit放在查询语句的最后

公式:要显示的页数 limit (page-1)*size,size

#分页查询

#查询前五条员工信息

SELECT * FROM employees LIMIT 0,5;

#2.查询第11-25条员工信息

SELECT * FROM employees LIMIT 10,15;

#3.有奖金的员工信息,并且将工资较高的前10条显示出来

SELECT * FROM employees WHERE commission_pct IS NOT NULL

ORDER BY salary

LIMIT 0,10;

九、联合查询

union 将多条查询语句的结果合并成一个结果

语法:

查询语句1

union

查询语句2

union

...

应用场景:查询的结果来自于多个表,且多个表没有直接的连接关系,但查询的信息一致时

特点: 要求多个查询语句的查询列表是一致的

多个查询语句的查询的每一列的类型和顺序最好是一致的

union关键字默认去重,如果使用union all可以包含重复项

#联合查询

#查询部门编号>90或邮箱包含a的员工信息

SELECT * FROM employees WHERE department_id > 90

UNION

SELECT * FROM employees WHERE email LIKE "%a%";

以上是 学习笔记:MYSQL查询 的全部内容, 来源链接: utcz.com/z/535486.html

回到顶部