SQL之数据查询语言DQL(超高频的数据查询,各类函数查询,分组查询,子查询一次让你学个爽)

SQL-DQL

DQL概述

DQL(Data Query Language):即数据查询语言,查询是数据库中使用频率最高的一个操作,可以从一个表中查询数据,也可以从多个表中查询数据。

关键字:select

基础语法

select 查询列表 form 表名;

特点:

1.查询列表可以是:表中的字段,常量,表达式,函数

2.查询的结果是一个虚拟的表格,查询中的操作不改变表格的原数据

本篇文章查询的基础表如下,建表和修改表的操作位于如下链接SQL之结构定义语言DDL(数据库的操作+数据库表的概述及操作), SQL之数据操纵语言DML(数据的增,删,改)
在这里插入图片描述

查询结果处理

1、查询常量值

select 常量 form 表名; 

在这里插入图片描述

2、查询表达式

select 表达式 from 表名;
例如 select 100*98;

3、查询函数

select 函数 from 表名;

函数: 类似于java中的方法,将一组逻辑语句事先在数据库中定义好,可以直接调用

好处:

(1) 隐藏了实现细节;

(2) 提高的代码的重用性.

调用:

select 函数名(实参列表) [from 表名]

在这里插入图片描述

大家可以看到,我从t_stu表中查询了版本号,获得了7条数据,而这7条数据并没有在我的表中存在,只是以我表中的格式出现了,这是大家需要注意的地方.

4、特定列查询

select 列1,列2,列3... from 表名;#最常用

在这里插入图片描述

5、全部列查询

select * from 表名;# *代表全部

在这里插入图片描述

6、排除重复列

select distinct 列1,列2,列3... from 表名;

在这里插入图片描述

7、算数运算符

“+”"-""*""/":这里的运算符只能做算数运算,没有其他的任何功能,且操作只表现在查询,不改变原数据.

SELECT stu_grade-10 FROM t_stu;
SELECT stu_grade+1000 FROM t_stu;
SELECT stu_grade*10 FROM t_stu;
SELECT stu_grade/10 FROM t_stu;

函数查询

单行函数

字符函数

1、length():获取参数值的字节个数;

SELECT LENGTH(stu_grade) FROM t_stu;

2、char_length():获取参数值的字符个数;

SELECT CHAR_LENGTH(stu_name) FROM t_stu;

3、concat(str1,str2…):拼接字符串;

SELECT CONCAT(stu_name,':',stu_grade)AS person_grade FROM t_stu;

AS是为这个新拼接的查询列重命名

在这里插入图片描述

4、upper()/lower():将字符串变成大写/小写;

SELECT LOWER(stu_name) FROM t_stu;

5、substring(str,起始位置,长度):截取字符串,位置从1开始;

SELECT SUBSTRING(stu_birth,1,4)AS stu_year FROM t_stu;

6、instr(str,指定字符串):返回子串第一次出现的索引,如果找不到返回0;

SELECT INSTR(stu_name,'T') FROM t_stu;

7、lpad/rpad(str,length,填充字符):用指定的字符实现左/右填充将str填充为指定长度;

SELECT LPAD(stu_name,7,'棒') FROM t_stu;
SELECT RPAD(stu_name,7,'棒') FROM t_stu;

8、replace(str,old,new):替换所有的子串;

SELECT REPLACE(stu_sex,'女','nv') FROM t_stu;

9、trim(str):去掉字符串前后的空格或子串,trim(指定子串 from 字符串);

SELECT LENGTH(TRIM(stu_id)) FROM t_stu;

10、trim(指定子串 from 字符串):去掉字符串的指定前后子串。

SELECT LENGTH(TRIM('a' FROM 'asssssa')) FROM t_stu;
逻辑处理

1、case when 条件 then 结果1 else 结果2 end;可以有多个when

SELECT stu_name,
	(CASE WHEN stu_status=1 THEN '已注册' ELSE '未注册' END) AS stu_status
	FROM t_stu;

在这里插入图片描述

2、ifnull(被检测值,默认值)函数检测是否为null,为null返回指定值,否则返回原值。

SELECT stu_name,
	IFNULL(stu_grade,'未录入成绩')AS grade
	FROM t_stu;

3、if函数:if else的效果

if(条件,结果1,结果2)#慢足条件出结果1,否则出结果2
SELECT stu_name,
	IF(stu_grade=98.9,'成绩一致',stu_grade)AS grade
	FROM t_stu;

在这里插入图片描述

数学函数

1、round(数值):四舍五入;

SELECT ROUND(stu_grade)AS grade FROM t_stu;

2、ceil(数值):向上取整,返回>=该参数的最小整数;

SELECT CEIL(stu_grade)AS grade FROM t_stu;

3、floor(数值):向下取整,返回<=该参数的最大整数;

SELECT FLOOR(stu_grade)AS grade FROM t_stu;

4、truncate(数值,保留的小数位数):截断,小数点后截断几位;

SELECT TRUNCATE(stu_grade,0)AS grade FROM t_stu;

5、mod(被除数,除数):取余,被除数为正,则为正,被除数为负,则为负;

SELECT MOD(stu_grade,10)AS grade FROM t_stu;

6、rand():获取随机数,返回0-1之间的小数。

SELECT stu_name,
	(stu_grade+RAND())AS rand_grade
	FROM t_stu;

在这里插入图片描述

日期函数

1、now():返回当前系统日期+时间;

SELECT NOW() FROM t_stu;

2、curdate():返回当前系统日期,不包含时间;

SELECT CURDATE() FROM t_stu;

3、curtime():返回当前系统时间,不包含日期;

SELECT CURTIME() FROM t_stu;

4、获取日期的指定部分,year()、month()、day()、hour()、minute()、second()

SELECT YEAR(stu_now),
	MONTH(stu_now),
	DAY(stu_now),
	HOUR(stu_now),
	MINUTE(stu_now),
	SECOND(stu_now) 
	FROM t_stu;

在这里插入图片描述

5、str_to_date():将指定日期格式的字符串转换为日期格式。

SELECT STR_TO_DATE('2021年1月15','%Y年%m月%d日') FROM t_stu;

在这里插入图片描述

6、date_format():将日期转为字符串。

SELECT DATE_FORMAT(stu_now,'%Y年%m月%d日') FROM t_stu;

在这里插入图片描述

7、datediff(date1,date2):返回两个日期相差的天数,date1-date2

SELECT DATEDIFF(stu_now,STR_TO_DATE(stu_birth,'%Y-%m-%d')) FROM t_stu;

在这里插入图片描述

符号 含义
%Y 年,4位
%m 月,数值00-12
%d 日,数值00-31
%H 小时,数值00-23
%i 分钟,数值00-59
%s 秒,数值00-59
%f 微秒
%T 时间,24小时(hh:mm:ss)
%j 年的天,数值001-366
%w 周的天,数值0=星期天-6=星期六

聚合函数

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

1.sum() : 求和

SELECT SUM(stu_grade),SUM(stu_birth) FROM t_stu;

2.avg() : 求平均值

SELECT AVG(stu_grade) FROM t_stu;

3.max() : 求最大值

SELECT MAX(stu_name) FROM t_stu;

4.min() : 求最小值

SELECT MIN(stu_age) FROM t_stu;

5.count() : 计数, 数据统计,统计有多少行数据,不算null

SELECT COUNT(stu_name),COUNT(stu_sex),COUNT(stu_ph) FROM t_stu;

在这里插入图片描述

注意:

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

(2)max,min,count可以处理任意类型

(3)以上聚合函数都会忽略null值

(4)count函数的单独使用一般会用count(*)统计所有行数

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

eg:统计男女生人数
SELECT COUNT(stu_id),stu_sex FROM t_stu GROUP BY stu_sex;

条件查询

用法: 使用where子句,将不满足条件的行全部过滤,where子句紧随from子句.

语法:select 结果 from 表名 where 条件;

1.比较运算符

= , !=或<> , > , < , >= , <= 

2.逻辑运算

and 与
or  或
not 非
/*
使用where子句,将不满足的条件筛掉,where子句紧随from子句
*/
SELECT stu_name FROM t_stu WHERE stu_sex = '男' ;
SELECT * FROM t_stu WHERE stu_sex = '女';
SELECT * FROM t_stu WHERE stu_grade>99;
SELECT * FROM t_stu WHERE stu_grade<99;

SELECT * FROM t_stu WHERE stu_grade>99 AND stu_grade<=100;

3.模糊查询

关键字like : 是否匹配与一个模式, 一般和通配符搭配使用,可以判断字符型数值或数值.

通配符: % 任意多个字符, 包含0个字符 _ 任意单个字符

between and 两者之间, 包含临界值;

in(a,b):判断某字段的值是否属于in列表中的某一项

注意: 判断数据是否为空使用 is null 或者 is not null

#模糊查询
SELECT stu_name FROM t_stu WHERE stu_name LIKE('苏%');
SELECT * FROM t_stu WHERE stu_name LIKE '%居%';
SELECT * FROM t_stu WHERE stu_name LIKE '%白';

#between and
SELECT * FROM t_stu WHERE stu_grade BETWEEN 99 AND 100;

#in()
SELECT * FROM t_stu WHERE stu_age IN(20,600);
SELECT * FROM t_stu WHERE stu_age NOT IN(20,600);

#判断为null
SELECT * FROM t_stu WHERE stu_ph IS NULL;

在这里插入图片描述
在这里插入图片描述

UNION操作符

1.union操作符用于连接两个以上的select语句的结果组合到一个结果集合中,要求两个查询列数相同

2.语法

#语法1
[sql 语句1]
union
[sql 语句2]

#语法2
[sql 语句1]
union all
[sql 语句2]

注意:

1.union all是直接连接, 取到的是所有值, 记录可能有重复, 记录可能有重复, union是取唯一值, 记录没有重复.

2.效率: union和union all关键字都是将两个结果集合并为一个, 但这两者从使用和效率上来说都有所不同.

(1)对重复结果的处理: union在进行表连接后筛掉重复的记录,union all不会去除重复记录

(2)对排序的处理: union将会按照字段的顺序进行排序; union all只是简单的将两个结果合并后就返回;

(3)从效率来说, union all要比union快很多, 所以, 如果可以确认的两个结果中不包含重复数据且不需要排序的话,南无就是用union all

SELECT stu_id,stu_name,stu_age,stu_grade FROM t_stu WHERE stu_age>600
UNION ALL
SELECT stu_id,stu_name,stu_age,stu_grade FROM t_stu WHERE stu_age<20;

在这里插入图片描述

排序

1.查询结果排序, 使用order by子句排序, 对原表数据无影响;

2.order by排序列, asc/desc, asc代表升序, desc代表的是降序, 默认为升序;

3.order by子句中可以支持单个字段, 多个字段, 表达式, 函数, 别名.

4.使用

/*
语法
order by 排序列  ASC/DESC
asc代表的是升序,desc代表的是降序
默认是升序
*/
SELECT
  (stu_grade+RAND())AS rand_grade -- 结果
FROM
  t_stu -- 表名
WHERE stu_grade IS NOT NULL -- where筛选条件,有where条件先执行where条件,对筛选后的结果进行排序
ORDER BY rand_grade DESC; -- order by子句 desc降序 asc升序

在这里插入图片描述

数量限制

limit子句: 对查询的显示结果限制数目(sql语句最末尾的位置)

数据库的行数选择是从0开始的, 与字符函数中的substring()截取的起始位置不同,一定要区分

作用: 对查询的结果有数目限制

应用: 分页查询

语法:

/*
语法1
select 结果 from 表名 limit 查询数量;
*/
SELECT
  * -- 结果
FROM
  t_stu -- 表名
WHERE stu_age IS NOT NULL 
ORDER BY stu_age DESC
LIMIT 4; -- 从第一行数据开始的查询数量

/*
语法2
select 结果 from 表名 limit 开始行数,查询数量; 
*/
SELECT
  * -- 结果
FROM
  t_stu -- 表名
WHERE stu_age IS NOT NULL 
ORDER BY stu_age DESC
LIMIT 2,3; -- 从排序后的第三行数据开始查询三条

/*
语法3 
select 结果 from 表名 limit 查询数量 offset 跳过的数据行数;
*/
SELECT
  * -- 结果
FROM
  t_stu -- 表名
WHERE stu_age IS NOT NULL 
ORDER BY stu_age DESC
LIMIT 3 OFFSET 2; -- offset指的是跳过2行数据,开始查询3行数据

分组查询

语法

select 分组函数,列(要求出现在group by的后面)
from 表名
[where 筛选条件]
group by 分组的列表
[having 分组后的筛选]
[order by子句]
[limit 子句 限制数量]

简单的就是

select 结果 from 表名 group by 分组列

-- 统计男生女生各有多少人
SELECT stu_sex,COUNT(*) FROM t_stu GROUP BY stu_sex;

-- 统计男生女生中的最高成绩
SELECT stu_sex,MAX(stu_grade) FROM t_stu GROUP BY stu_sex;

注意: 查询列表比较特殊, 要求是分组函数和group by后出现字段

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

数据源 源位置 关键字
分组前筛选 原始表 group by子句的前面 where
分组后筛选 分组后的结果集 group by的后面 having
-- 查询性别人数大于2的是哪个性别,对分组后的结果进行条件的筛选
SELECT stu_sex,COUNT(*)AS c
FROM t_stu
WHERE stu_grade > 0 -- 在分组前对数据进行筛选过滤
GROUP BY stu_sex
HAVING c>2 -- 分组后对条件进行筛选过滤
ORDER BY c DESC;

子查询

1.含义: 出现在其它语句( insert,update,delete,select )中的select语句,称为子查询或内查询; 外部的查询语句,称为主查询或外查询

-- 在insert 语句中使用子查询,不能为要添加的数据字段加唯一索引
INSERT INTO t_stu(stu_name,stu_sex,stu_grade,stu_age) 
SELECT stu_name,stu_sex,stu_grade,stu_age
FROM t_stu
WHERE stu_id = 5;

-- 在update 语句中使用子查询 注意查询的结果不能在本张表中查询
#先创建一张新表
CREATE TABLE stu_temp(
	stu_id SMALLINT,
	stu_name VARCHAR(10),
	stu_sex CHAR(1) DEFAULT'男'
)
UPDATE t_stu 
SET stu_name='王五' 
WHERE stu_name = (
	SELECT stu_name 
	FROM stu_temp 
	WHERE stu_id = 1
)

-- 在delete 语句中使用子查询 准备查询的结果不能在本张表中查询
DELETE
FROM t_stu
WHERE stu_id = (
	SELECT stu_id
	FROM stu_temp
	WHERE stu_name = '王五'
)

2.按功能,结果集的行列数不同分为:

(1)标量子查询: 结果集只有一行一列;

(2)列子查询: 结果集只有一列多行;

(3)行子查询: 结果集有一行多列;

(4)表子查询: 结果集为多行多列

3.注意:

(1)select语句后面: 仅仅支持标量子查询;

(2)from后面: 仅仅支持表子查询;

(3)where或having后面:支持标量子查询,列子查询,行子查询(较少);

(4)exists后面(相关子查询):支持表子查询.

-- 在select语句后面加子查询,只能是标量子查询
SELECT stu_name,(SELECT NOW()),stu_id 
FROM t_stu;

-- from后面:支持表子查询 查询性别大于4的是哪个性别
SELECT * FROM
	(SELECT stu_sex,COUNT(*)c FROM t_stu GROUP BY stu_sex)t -- 把查询结果当成一张表
	WHERE t.c>4;

-- 列子查询 查询年龄大于100的所有信息
SELECT * 
FROM t_stu
WHERE stu_age IN(
	SELECT stu_age
	FROM t_stu
	WHERE stu_age > 100
)

-- 行子查询
#查询学号最大,成绩最高的学生,需要同时满足
SELECT * 
FROM t_stu 
WHERE (stu_id,stu_grade) = (
	SELECT MAX(stu_id),MAX(stu_grade)
	FROM t_stu
)

猜你喜欢

转载自blog.csdn.net/Lotus_dong/article/details/112662263