上篇博文给大家介绍了DQL语言的部分知识点,这篇博文给大家结合案例继续更新其他查询语句…
多表查询
等值连接查询
等值连接查询多张表的特点:
多表等值连接的结果为多表的交集部分
n表连接,至少需要n-1个连接条件
多表的顺序没有要求
一般需要为表起别名
可以搭配前面介绍的所有子句使用,比如排序、分组、筛选
语句:
SELECT e.查询字段,e.查询字段,j.查询字段
FROM 表1 e,表2 j
WHERE e.表1交接列=j.表2交集列;
注意:这里的e
和j
都是别名,随便取任意字符就行…
非等值连接
#查询员工的工资和工资级别
SELECT salary,grade_level
FROM 表1 e,表2 g
WHERE e.salary BETWEEN g.`lowest_sal` AND g.`highest_sal`
AND g.`grade_level`='A';
join连接
#语法:
select 查询列表 from 表1 别名 连接类型
join 表2 别名
on 连接条件
内连接
#特点:
#1、添加排序、分组、筛选
#2、inner可以省略
#3、筛选条件放在where后面,连接条件放在on后面,提高分离性,便于阅读
#4、inner join连接和sql92语法中的等值连接效果是一样的,都是查询多表的交集
select 查询列表
from 表1 别名
inner join 表2 别名
on 连接条件;
外连接
#特点:
#1、外连接的查询结果为主表中的所有记录
#如果从表中有和它匹配的,则显示匹配的值
#如果从表中没有和它匹配的,则显示null
#外连接查询结果=内连接结果+主表中有而从表没有的记录
#2、左外连接,left join左边的是主表
# 右外连接,right join右边的是主表
#3、左外和右外交换两个表的顺序,可以实现同样的效果
#4、全外连接=内连接的结果+表1中有但表2没有的+表2中有但表1没有的
#左外连接
SELECT b.*,bo.*
FROM 表1 bo
LEFT OUTER JOIN 表2 b
ON b.连接列字段名 = bo.连接列字段名
#右外连接
SELECT d.*,e.查询字段
FROM 表1 e
RIGHT OUTER JOIN 表2 d
ON d.连接列字段名 = e.连接列字段名
#全外
SELECT b.*,bo.*
FROM 表1 b
FULL OUTER JOIN 表2 bo
ON b.连接列字段名 = bo.连接列字段名;
#交叉连接
SELECT b.*,bo.*
FROM 表1 b
CROSS JOIN 表2 bo;
常见函数
#字符函数:
length:获取字节个数(utf-8一个汉字代表3个字节,gbk为2个字节)#返回子串第一次出现的索引,如果找不到返回0
SELECT LENGTH('john');
--> 4
concat#拼接
SELECT CONCAT("Hello",'_',"World");
-->Hello_World
substr#截取(从第几位数开始截取)
SELECT SUBSTR('HelloWorld',7);
-->orld
instr#返回子串第一次出现的索引,如果找不到返回0
SELECT INSTR('HelloWorld','W') AS out_put;
-->6
trim#去掉左右空格,还有其他用法 SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx'); --删除指定的首字符 x等等
SELECT TRIM(' 张翠山 ') AS out_put;
-->张翠山
upper#转大写
SELECT UPPER('john');
-->JOHN
lower#转小写
SELECT LOWER('joHn');
-->john
lpad#用指定的字符实现左填充指定长度
SELECT LPAD('殷素素',4,'1') AS out_put;
-->1殷素素
rpad#用指定的字符实现右填充指定长度
SELECT RPAD('殷素素',4,'1') AS out_put;
-->殷素素1
replace#替换
SELECT REPLACE('HelloWorld','World','Java') AS out_put;
-->HelloJava
#数学函数:
round#四舍五入
SELECT ROUND(-1.55);
-->-2
ceil#向上取整,返回>=该参数的最小整数
SELECT CEIL(-1.02);
-->-1
floor#向下取整,返回<=该参数的最大整数
-->-10
truncate#截断
SELECT TRUNCATE(1.69999,1);
-->1.6
mod#取余
SELECT MOD(10,3);
-->1
#日期函数:
now#返回当前系统日期+时间
SELECT NOW();
-->2020-06-17 19:39:45
curdate#返回当前系统日期,不包含时间
SELECT CURDATE();
-->2020-06-17
curtime#返回当前时间,不包含日期
SELECT CURTIME();
-->19:40:50
#可以获取指定的部分,年、月、日、小时、分钟、秒
year#获取当前时间的年份
SELECT YEAR(NOW()) 年;
-->2020
month#获取当前时间的月份
SELECT MONTH(NOW()) 月;
-->6
monthname#获取月份英文名
SELECT MONTHNAME(NOW()) 月;
-->June
day#同上案例
hour#同上案例
minute#同上案例
second#同上案例
str_to_date#将字符通过指定的格式转换成日期
SELECT STR_TO_DATE('1998-3-2','%Y-%c-%d') AS out_put;
-->1998-03-02
date_format#将日期转换成字符
SELECT DATE_FORMAT(NOW(),'%y年%m月%d日') AS out_put;
-->20年06月17日
#其他函数:
version#获取数据库版本号
SELECT VERSION();
database#获取当前使用数据库名
SELECT DATABASE();
user#获取当前连接用户名
SELECT USER();
#控制函数
if# if else 的效果
SELECT IF(10<5,'大','小');
-->小
case
#
#case 要判断的字段或表达式
#when 常量1 then 要显示的值1或语句1;
#when 常量2 then 要显示的值2或语句2;
#...
#else 要显示的值n或语句n;
#end
子查询
以下表和列字段仅作为举例参考,实际情况根据自己的数据库表处理…
#where或having后面
#查询员工的信息,满足 salary>①结果
SELECT *
FROM t_mysql_employees
WHERE salary>(
SELECT salary
FROM t_mysql_employees
WHERE last_name = 'Abel'
);
#查询员工的姓名,job_id 和工资,要求job_id=.... 并且要求salary>...
SELECT last_name,job_id,salary
FROM t_mysql_employees
WHERE job_id = (
SELECT job_id
FROM t_mysql_employees
WHERE employee_id = 141
) AND salary>(
SELECT salary
FROM t_mysql_employees
WHERE employee_id = 143
);
#查询最低工资>id=50的最低工资和id
SELECT MIN(salary),department_id
FROM t_mysql_employees
GROUP BY department_id
HAVING MIN(salary)>(
SELECT MIN(salary)
FROM t_mysql_employees
WHERE department_id = 50
);
#select后面
#查询每个部门的员工个数
SELECT d.*,(
SELECT COUNT(*)
FROM t_mysql_employees e
WHERE e.department_id = d.`department_id`
) 个数
FROM t_mysql_departments d;
#from后面
#查询每个部门的平均工资
1、SELECT AVG(salary),department_id
FROM t_mysql_employees
GROUP BY department_id;
2、SELECT * FROM t_mysql_job_grades;
2连接1的结果集和job_grades表,筛选条件平均工资 between lowest_sal and highest_sal
SELECT ag_dep.*,g.`grade_level`
FROM (
SELECT AVG(salary) ag,department_id
FROM t_mysql_employees
GROUP BY department_id
) ag_dep
INNER JOIN job_grades g
ON ag_dep.ag BETWEEN lowest_sal AND highest_sal;
#exists后面
SELECT department_name
FROM t_mysql_departments d
WHERE EXISTS(
SELECT *
FROM t_mysql_employees e
WHERE d.`department_id`=e.`department_id`
);
分页查询
应用点:当要显示的数据,一页显示不全,需要分页提交sql请求
#语法:
select 查询列表
from 表
【join type join 表2
on 连接条件
where 筛选条件
group by 分组字段
having 分组后的筛选
order by 排序的字段】
limit 【offset,】size;
#offset要显示条目的起始索引(起始索引从0开始)
#size 要显示的条目个数
#案例1:查询前五条员工信息
SELECT * FROM t_mysql_employees LIMIT 0,5;
SELECT * FROM t_mysql_employees LIMIT 5;
#案例2:查询第11条——第25条
SELECT * FROM t_mysql_employees LIMIT 10,15;
分组查询案例(结合分组函数)
语法:
select 查询列表 from 表名 where 筛选条件 group by 分组的字段 order by 排序的字段;
特点:
- 和分组函数一同查询的字段必须是group by后出现的字段
- 筛选分为两类:分组前筛选和分组后筛选
分组前筛选: 原始表group by
前where
分组后筛选:group by
后的结果集group by
后having
- 分组可以按单个字段也可以按多个字段
- 可以搭配着排序使用
注意点:
- 分组函数做筛选不能放在
where
后面 - 一般来讲,能用分组前筛选的,尽量使用分组前筛选,提高效率
案例:
这里使用的是我自己数据库的一张职位表,结合这张表给大家做个案例分析:
#案例1:查询每个岗位平均工资
SELECT AVG(salary),job
FROM t_solr_job
GROUP BY job;
查询结果:
#案例2:查询职位中包含j字符的 每个职位的最高工资
SELECT MAX(salary),job
FROM t_solr_job
WHERE job LIKE '%j%'
GROUP BY job;
#案例3.查询各职位的工资的最大值,最小值,平均值,总和,并按工资升序
SELECT MAX(salary),MIN(salary),AVG(salary),SUM(salary),job
FROM t_solr_job
GROUP BY job
ORDER BY salary;
总结
DQL语言的知识点到这就差不多了,贴上个人总结的脑图结合使用:
尾言
博文内容比较多,整理了比较久,知识点也比较多,注意慢慢消化,好好掌握…