数据库------DQL操作

DQL

数据查询语言 ,主要用来查询数据,使用的命令是 select

常见的查询方式

  • SimpleQuery
  1. 简单查询
  2. 基于表的查询
  3. 条件查询
  4. 分组查询
  5. 分组筛选查询
  6. 排序
  7. 分页
  • SubQuery (子查询)
  1. 基于列的子查询
  2. 基于条件的子查询
  • 嵌套查询
  • 关联查询
  • 集合查询
  • with查询

SimpleQuery

  • 简单查询
select 1 ;

-- 查询当前系统时间 
select now();

-- 查询数据库的版本
select version();

-- 查询当前登录用户信息
select user();

pS: 主要可以做 数据库 集群之间的 心跳检测

  • 基于表的查询
select column... from <tableName> ;

查询的 column … 多个列用 逗号 分割
如果要查询所有字段,可以使用 * 来代替查询的所有列,但在实际开发中,不推荐使用 *

  • 基于条件的查询
    1. 关系条件查询
    2. 逻辑条件查询
    3. 区间查询
    4. 枚举查询
    5. 空值查询
    6. 模糊查询
select column ... from <tableName> where 条件 ;
  • 聚合函数

    • count() : 统计 个数 、
    • max() : 求 最大值
    • min() : 求 最小值
    • sum() : 求 和
    • avg() : 求 平均值
-- 查询 学生表中的 学生个数 

-- 会将每一行当作一条记录进行统计
select count(*) from tb_student; 
-- 如果按照字段统计 、那么字段的值如果是空,则不参与统计
select count(id) from tb_student ;
-- 
select count(1) from tb_student ;

当 统计的字段是 主键的时候,执行效率是: count(id) > count(1) > count()
当 统计的字段是 普通字段时, 执行效率是 : count(1) > count(column) > count("
")
聚合函数不对空值null进行统计

  • 分组查询 group by
-- 查询 学生中, 各个系 有多少人 

select tie_id , count(id) from tb_student group by tie_id ;

分组对查询的列有要求 a) 查询的列出现在 聚合函数中, b) 查询的列出现在 group by 后
如果查询的列中出现了 聚合函数 和 普通的列 ,那么 该 SQL应该需要用到分组

  • 分组筛选查询 having
-- 根据年龄分组 、并查询 组成员数 > 3 的 组
select * from tb_student group by age having count(1)>3 ;
-- 查询 班级中 相同名字的 学生名 
select name from tb_student group by name having count(1)>1 ;

having 必须在分组后才能使用, 而 where 是对表中的所有数据进行过滤,从执行效率上, where 比 having 高
从执行顺序上、where 优于 having 先执行。 能用 where 筛选数据尽量不要用 having 筛选

  • 排序 order by
    • asc : 升序排列
    • desc : 降序排列
-- 查看所有的语文成绩、并按照成绩降序排列
select * from tb_score where score = '语文' order by score desc ;
  • 分页查询 limit
select * from tb_score limit [<offset>, ] <rows> ;

offset : 偏移量,默认从 0 开始, 如果没有 offset, 则默认是 0
rows : 用来设置每页显示的条数
page : 代表页码
pages : 代表 总页数
total : 代表 总条数

offset = (page - 1) * rows ;

pages = (total -1 )/rows + 1 ;

简单查询的完整命令

select column... from <tableName> 

where 条件 

group by 分组字段列表 

having  筛选条件 

order by 排序字段列表 

limit [<offset> ,] <rows>

SubQuery

子查询 可以更好的去查询想要的数据、是一种比较特殊的 嵌套查询

  • 基于 列的子查询
  • 基于 条件的子查询

基于列的子查询

在 查询的 列中, 包含一个 查询语句

-- 查询 ID = 1000 的 学生名、系ID、系名
select t.id , 
		  t.name , 
		  t.tie_id, 
	      (select x.name from tb_tie x where x.id = t.tie_id) as xname
from tb_student t where t.id = 1000;

子查询的结果必须是单列、单值

基于条件的子查询

在查询条件上、包含一个 查询语句

  • 关系条件子查询
-- 查询 语文最高成绩对应的学号 

select stu_id from tb_score t where score = 
  (select max(score) from tb_score s where s.subject =  t.subject)
and subject = '语文'; 

-- 查询 成绩 超过 语文的平均成绩的 学号 
select s.stu_id from tb_score s where 
s.score > (select avg(x.score) from tb_score x where x.subject = '语文')

关系条件子查询要求子查询返回单列单值

  • in 条件子查询
-- 查询 每一个科目的最高成绩对应的学生信息 

select * from tb_student where id in 
(
	select stu_id from tb_score f 
		where  score = (select  max(score) from tb_score x where x.subject = f.subject) 
);

in条件子查询要求返回单列多值

  • exists 条件子查询
select * from tb_student t where exists 
(
	  select 1 from tb_score f 
		where f.score =  (select max(score) from tb_score x where x.subject = f.subject)
		and f.stu_id = t.id 
);

exists子查询有结果就代表存在,否则代表不存在

嵌套查询

将一个查询的结果当作一张表 继续查询


select b.* from (
	select * from tb_student
) b

嵌套查询要求必须给表起别名

with 查询

当一个查询的结果 在 SQL 被多次使用, 可以 使用 with 建立临时表 进行查询

with temp as ( select * from tb_student) select * from temp ;

关联查询

表与表之间 存在什么关系??? 数据与数据之间存在什么关系???

  • One-To-One :
  • Many-To-One:
  • One-To-Many:
  • Many-To-Many:

一对一的关联关系

用户表: (id、用户名、密码、注册时间、最近一次登录时间、最近登录IP地址、账户的状态)

用户信息表 (ID, 身份证号、个人头像、性别、出生日期、手机号、邮箱)

create table tb_user(
	id bigint primary key auto_increment ,
	username varchar(50) unique not null comment '用户名' ,
	password varchar(128) not null comment '密码', 
	last_login_time datetime comment '最近登录时间', 
	ip_addr varchar(100) comment '最近登录IP', 
	status tinyint default 0 comment  '-1 注销 0 未激活  1 正常  -2 拉黑' ,
	create_time datetime comment '注册时间' 
);

-- 常规创建
create table tb_user_info (
   id bigint primary key auto_increment ,
   card varchar(18) comment '身份证号', 
   photo varchar(200) comment '头像地址' ,
   sex enum('m', 'f', 's') default 's' comment '性别' ,
   birth date comment '出生日期', 
   tel varchar(11) comment '手机号', 
   email varchar(50) comment '邮箱' ,
   -- 维护关系
   user_id bigint unique, 
   -- 添加外键约束 	
   foreign key(user_id) references tb_user(id)
) ;

-- 主键共享 
create table tb_user_info (
   id bigint primary key auto_increment ,
   card varchar(18) comment '身份证号', 
   photo varchar(200) comment '头像地址' ,
   sex enum('m', 'f', 's') default 's' comment '性别' ,
   birth date comment '出生日期', 
   tel varchar(11) comment '手机号', 
   email varchar(50) comment '邮箱' ,
   foreign key(id) references tb_user(id)
) ;

多对一 或者 一对多 的关联关系

是关系型数据库最擅长处理的关系、也是 生活中最常见的关联关系
关联关系 由多的一方进行维护

create table tb_resource_type(
	id bigint primary key auto_increment ,
	name varchar(100) comment '资源类型名称' ,
	pid  bigint ,
	foreign key(pid) references tb_resource_type(id)
) ;

create table tb_resource(
   id bigint primary key auto_increment, 
   name varchar(200) comment '资源名称' ,
   descp text comment '资源描述', 
   keywords varchar(200) comment '关键字', 
   
   type_id bigint comment '资源类型ID', 
   
   score int comment '资源积分' ,
   resource varchar(200) comment '资源路径', 
   size bigint comment '文件大小', 
   ext varchar(20) comment '资源扩展名' ,
   create_time datetime comment '资源上传时间' ,
	
   user_id bigint comment '上传者' ,
   
   foreign key (type_id) references tb_resource_type(id) ,
   foreign key(user_id) references tb_user(id)
);

多对多关联关系

关系型数据库最不擅长处理的关系
多对多的关联关系 采用 中间表 进行维护

create table tb_role(
   id bigint primary key auto_increment ,
   name varchar(100) comment '角色名' , 
   descp varchar(500) comment '角色描述' ,
   status boolean default 1 comment '角色状态是否启用'
);

-- 用户和角色 中间表 (常规建表方式)
create table tb_role_user(
	id bigint primary key auto_increment ,
	role_id bigint ,
	user_id bigint ,
	foreign key(role_id) references tb_role(id), 
	foreign key(user_id) references tb_user(id)
);

-- 联合主键 构建中间表
create table tb_role_user(
	role_id bigint ,
	user_id bigint ,
	foreign key(role_id) references tb_role(id), 
	foreign key(user_id) references tb_user(id),
	
	primary key(role_id , user_id)
);

关联查询

  • inner join : 内链接查询、可以省略 inner 关键字

  • left outer join : 左外链接查询, 可以省略 outer 关键字

  • right outer join : 右外链接查询,可以省略 outer 关键字

笛卡尔积(不推荐)

将多张表 合并在一块进行查询

select r.*, t.name as typename from tb_resource r,  tb_resource_type t 
	where r.type_id = t.id ;

性能极低: 两张表会进行交叉组合、形成一个超级代表,表的数据量rows = A表的rows * B表的rows

关联查询


select .... from A表  
	
	[left/right/inner] join B表  on 关联条件 
	
where ....

集合查询

  • 并集
  • 交集
  • 差集

MySQL数据库只支持并集查询

并集 union / union all

将两个 SQL 使用 union / union all 合并在一块 形成一个 SQL
union 会对两个 SQL 查询的结果 进行去重
union all 仅仅将两个 SQL结果进行合并,不会去重

两个SQL查询的字段个数必须一致、含义一一对应

猜你喜欢

转载自blog.csdn.net/weixin_52953038/article/details/126660985
今日推荐