MySQL多表联查常用函数数据库设计规范
文章目录
- 1多表联查
- 1.1 表和表之间的关系
- 1.2 合并结果集(联合查询)
- 1.3 连接查询
- 1.3.1 内连接
- 1.3.2 外连接
- 1.4 子查询(subquery)
- 2 函数
- 2.1 字符串函数
- 2.2 数学函数
- 2.3 日期函数
- 2.4 字符-日期互转
- 2.5 流程控制函数
- 3 数据库设计
- 数据库设计流程
- 数据库设计的三范式
1多表联查
1.1 表和表之间的关系
一对一
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pfOpQerS-1660738943044)(day27-mysql.assets/image-20220817093215178.png)]
一对多
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3tCMQsnf-1660738943045)(day27-mysql.assets/image-20220817093928691.png)]
多对多
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3ndTAEtm-1660738943046)(day27-mysql.assets/image-20220817094606629.png)]
1.2 合并结果集(联合查询)
合并结果集就是将多个查询结果,纵向拼接在一起。
语法
select * from tb_a
union
select * from tb_b
--================================
select id,name,age from tb_a
union all
select birthday,name,age from tb_b
/*
union 会将完全一致的数据去重
union all 会将所有数据保留
合并的两表的列数,数据类型要一致!!
ps: 一般用在将一个大表拆成两个表是,这两张表的拼接使用
*/
1.3 连接查询
连接查询是将多个表的查询结果,横向拼接后展现
1.3.1 内连接
/*语法:
select * from tb1 inner join tb2 on tb1.字段 = tb2.字段;
*/
-- 查询学生信息以及对应的班级信息
-- 一定要加关联条件,否则会产生"笛卡尔积"
select * from stu inner join class on stu.cid = class.cid
-- 内连接只会保留完全符合关联条件的数据-- 内连接的简化写法
select * from stu s,class c where s.cid = c.cid
-- 查询学生编号为1007的学生名称、学生成绩、班级名称、班级地址
select s.sname,s.score,c.cname,c.caddress from stu s,class c where s.cid = c.cid and s.sid = 1007
内连接只会保留完全符合关联条件的数据
1.3.2 外连接
外连接分左外连接和右外连接.
外连接会保留不符合关联条件的数据,左外保留左表中不符合条件的数据,右外保留右表中不符合条件的数据,
/*
语法: select * from tb1 left outer join tb2 on tb1.字段 = tb2.字段
*/
-- 查询学生信息,如果有班级信息就查询班级信息
select * from stu left outer join class on stu.cid = class.cid;
select * from stu left join class on stu.cid = class.cid;
select * from stu right outer join class on stu.cid = class.cid;
-- 可以省略outer
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X0X5Fbin-1660738943046)(day27-mysql.assets/image-20220817102728760.png)]
1.4 子查询(subquery)
子查询其实就是嵌套查询
子查询嵌套,
可以嵌套在where后面当条件,
可以嵌套在from后面当表
-- 查询与张三同一个班级的学生。(子查询当条件)
-- 1) 先找到张三所在班级
select cid from stu where sname = '张三'
-- 2) 找到1班所有人
select * from stu where cid = 1
-- 改造成:子查询
select * from stu where cid =
(select cid from stu where sname = '张三')-- =======================================================================/*
子查询当条件时需要注意返回的结果的个数
如果是一个返回值,条件可以使用=,>,<,等等
如果是多个返回值,条件用in
*/
select * from stu where cid in
(select cid from stu where age = 45)-- =======================================================================-- 成绩高于3号班级所有人的学生信息
-- 1) 查询3班最高分
select max(score) from stu where cid = 3;
-- 2) 大于最高分
select * from stu where score > 96;
-- 改造
select * from stu where score >
(select max(score) from stu where cid = 3)-- =======================================================================-- 有2个以上直接组员的学生信息
-- 2个以上组员的组长编号,组内人数
select groupLeaderId,count(sid) from stu group by groupLeaderId having count(sid) > 2
-- 查询组长信息
select * from stu where sid in (1007,1010)
-- 改造
select * from stu where sid in
(select groupLeaderId from stu group by groupLeaderId having count(sid) > 2)-- =======================================================================-- 变式写法:子查询当表
select * from stu s,(select groupLeaderId,count(sid) from stu group by groupLeaderId having count(sid) > 2) z
where s.sid= z.groupLeaderId-- =======================================================================-- 求1008学生编号、姓名、组长编号和组长姓名
select s.sid,s.sname,s.groupLeaderId,z.sname from stu s,stu z where s.groupLeaderId = z.sid and s.sid =1008-- =======================================================================-- 查询每个学生成绩大于等于60且成绩总和大于200的班级编号以及成绩和并根据成绩和升序
select sum(score),cid from stu group by cid having min(score) >=60 and sum(score) > 200 order by sum(score);-- =======================================================================-- 自连接
-- 查询学生信息以及对应的组长信息
select * from stu s,stu z where s.groupLeaderId = z.sid
2 函数
2.1 字符串函数
函数 | 说明 |
---|---|
CHARSET(str) | 返回字串字符集 |
CONCAT (string2 [,… ]) | 连接字串 |
INSTR (string ,substring ) | 返回substring在string中出现的位置,没有返回0 |
UCASE (string2 ) | 转换成大写 |
LCASE (string2 ) | 转换成小写 |
LEFT (string2 ,length ) | 从string2中的左边起取length个字符 |
LENGTH (string ) | string长度 |
REPLACE (str ,search_str ,replace_str ) | 在str中用replace_str替换search_str |
STRCMP (string1 ,string2 ) | 逐字符比较两字串大小, |
SUBSTRING (str , position [,length ]) | 从str的position开始,取length个字符 |
LTRIM (string2 ) RTRIM (string2 ) trim | 去除前端空格或后端空格 |
-- concat连接
select concat(ename,'-',job) from emp;
select concat('姓名:',ename,',职位:',job) from emp;
-- 查询字符串位置
select instr('abcde','bc') from dual;-- 替换
select replace(ename,'A','a') from emp;
-- 截取字符串(截取姓名最后2位)
select substring(ename,length(ename)-1) from emp;
-- 截取字符串(截取姓名倒数第2位)
select substring(ename,length(ename)-1,1) from emp;
-- 增删改也可以使用函数
update tb_a set name = substring('asdfafasfasf',2,3) where id = 3
-- where后不能使用聚合函数,但是可以使用普通函数
select * from emp where length(ename) > 5;
2.2 数学函数
函数 | 说明 |
---|---|
ABS (number2 ) | 绝对值 |
BIN (decimal_number ) | 十进制转二进制 |
CEILING (number2 ) | 向上取整 |
CONV(number2,from_base,to_base) | 进制转换 |
FLOOR (number2 ) | 向下取整 |
FORMAT (number,decimal_places ) | 保留小数位数 |
HEX (DecimalNumber ) | 转十六进制 |
LEAST (number , number2 [,…]) | 求最小值 |
MOD (numerator ,denominator ) | 求余 |
RAND([seed]) | RAND([seed]),seed是种子,可不写.写了随机数固定 |
round(x,[d]) | 将x四舍五入,d是保留的位数,可不写 |
truncate(x,d) | 将x数值保留d为小数(截断) |
select abs(-111) from emp;
-- 格式化
select format(sal,1) from emp;
-- 随机数(0~1之间的小数)
insert into stu (sid) values(rand()*10)
select rand() from dual;
-- 设置种子后,会产生固定随机数
select rand(1) from dual;
-- 四舍五入
select round(1.55,1) from dual;
-- 截断,保留的小数位数
select truncate(1.99,0) from dual;
2.3 日期函数
函数 | 说明 |
---|---|
sysdate() | 获得当前系统时间 |
ADDTIME (date2 ,time_interval ) | 将time_interval加到date2 |
CURRENT_DATE ( ) | 当前日期 |
CURRENT_TIME ( ) | 当前时间 |
CURRENT_TIMESTAMP ( ) | 当前时间戳 |
DATE (datetime ) | 返回datetime的日期部分 |
DATE_ADD (date2 , INTERVAL d_value d_type ) | 在date2中加上日期或时间 |
DATE_SUB (date2 , INTERVAL d_value d_type ) | 在date2上减去一个时间 |
DATEDIFF (date1 ,date2 ) | 两个日期差 |
NOW ( ) | 当前时间 |
YEAR|Month|DATE (datetime ) | 年|月|日 |
-- 获得当前时间
select sysdate() from dual;
select current_date() from dual;
select current_time() from dual;
select concat(current_date(),' ',current_time()) from dual;
select current_timestamp() from dual;
select now() from dual;
insert into emp(empno,hiredate)
values(rand()*100,sysdate());-- 增加时间
select addtime('2022-08-17 23:00:00','2:00:00') from dual;
-- 增加日期adddate(expr1,days)
select adddate('2020-08-01',30) from dual; -- 加指定天数
-- 增加日期adddate(date,INTERVAL expr type)
-- 加指定单位的日期
select adddate('2020-08-01', 1 year) from dual;
select adddate('2020-08-01',interval 1 month) from dual;
select adddate('2020-08-01',interval 1 day) from dual;
select adddate('2020-08-01 10:00:00',interval 1 hour) from dual;
select adddate('2020-08-01 10:00:00',interval 10 minute) from dual;
select adddate('2020-08-01 10:00:00',interval 70 second) from dual;
-- 时间相加(与adddate同义词)
select date_add('2020-01-01',interval 30 day) from dual;
-- 时间相减subdate() 和date_sub()同义词
select date_sub('2020-10-01',interval 1 year) from dual;
-- 时差,返回两个时间之间的天数
select datediff('2020-01-01',sysdate()) from dual;-- 获取部分日期时间
select date(sysdate()) from dual;
select year(sysdate()) from dual;
select month(sysdate()) from dual;
select day(sysdate()) from dual;
2.4 字符-日期互转
日期格式化字符串 date_format(date,‘%Y-%m-%d’)
字符串解析为日期 str_to_date(date,‘%Y-%m-%d’)
格式化符号
%Y:代表4位的年份%y:代表2位的年份%m:代表月, 格式为(01……12)%c:代表月, 格式为(1……12)%d:代表月份中的天数,格式为(00……31)%e:代表月份中的天数, 格式为(0……31)%H:代表小时,格式为(00……23)%k:代表 小时,格式为(0……23)%h: 代表小时,格式为(01……12)%I: 代表小时,格式为(01……12)%l :代表小时,格式为(1……12)%i: 代表分钟, 格式为(00……59)%r:代表 时间,格式为12 小时(hh:mm:ss [AP]M)%T:代表 时间,格式为24 小时(hh:mm:ss)%S:代表 秒,格式为(00……59)%s:代表 秒,格式为(00……59)
-- 日期和字符串互相转换
-- 日期-->字符串 date_format
select date_format(sysdate(),'%Y年%m月%d日') from dual;
-- 字符串-->日期 str_to_date
select str_to_date('2020年01月01日','%Y年%m月%d日') from dual;-- 插入时使用日期
insert into emp (hiredate)
values(str_to_date('2020年01月01日','%Y年%m月%d日'));
2.5 流程控制函数
函数 | 说明 |
---|---|
IF(expr1,expr2,expr3) | 如果expr1为真,则返回expr2,否则返回expr3 |
IFNULL(expr1,expr2) | 如果 expr1不是NULL,则返回expr1,否则返回expr2; 一般用来替换NULL值,因为NULL值是不能参加运算的 |
CASE WHEN [expr1] THEN [result1]… ELSE [default] END | 如果expr是真, 返回result1,否则返回default |
CASE [value] WHEN [value1] THEN[result1]… ELSE[default] END | 如果value等于value1, 返回result1,否则返回default |
-- if()
select if(1<0,'a','b') from dual;
select avg(if(sal is null,0,sal)) from emp;
select avg(sal) from emp;
-- 列出学生成绩,如果为null,显示缺考
select sname,if(score is null,'缺考',score) from stu;
-- ifnull()
select sname,ifnull(score,'缺考') from stu;
-- case when
select case 5 when 1 then '一'
when 2 then '二'
when 3 then '三'
else 4
end as 结果
from dual;-- case when
select case when 1 < 0 then '一'
when 1 > 2 then '二'
else 3
end as 结果
from dual;
-- 给学生成绩设置等级
-- 0-59 不及格,60-70 及格,71-80 中等 81-90 良好 91-100优秀
select sname,score, case
when score < 60 then '不及格'
when score < 71 then '及格'
when score < 81 then '中等'
when score < 91 then '良好'
else '优秀' end 等级
from stu;
3 数据库设计
MySQL数据库作为数据存储的介质为应用系统提供数据存储的服务,我们如何设计出合理的数据库、数据表以满足应用系统的数据存储需求呢?
• 车库:是用来存放车辆的,车库都需要划分车位,如果不划分车位,车子杂乱无章的存放可能会导致车辆堵塞,同时也可能造成场地的浪费,好的车库的规划应该是有限的场地能够停放最多的车辆,同时方便每一辆车的出入
• 数据库,是用来存放数据的,我们需要设计合理的数据表,能够完成数据的存储,同时能够方便的提取应用系统所需的数据
数据库设计流程
数据库是为应用系统服务的,数据库存储什么样的数据也是由应用系统来决定的。当我们进行应用系统开发时,我们首先要明确应用系统的功能需求,也就是软件系统的需求分析
- 根据应用系统的功能,分析数据实体(实体,就是要存储的数据对象)
电商系统:商品、用户、订单…
教务管理系统:学生、课程、成绩…
- 提取实体的数据项(数据项,就是实体的属性)
商品(商品名称、商品图片、商品描述…)
用户(姓名、登录名、登录密码…
- 根据数据库设计三范式规范视图的数据项
检查实体的数据项是否满足数据库设计三范式
如果实体的数据项不满足三范式,可能会导致数据的冗余,从而引起数据维护困难、破坏数据一致性等问题
绘制E-R图 (实体关系图,直观的展示实体与实体之间的关系)
矩形代表实体
椭圆形代表属性
菱形代表关系
实线关联
数据库建模
○ 三线图进行数据表设计
○ PowerDesigner
○ PDManer
- 建库建表 编写SQL指令创建数据库、数据表
添加测试数据,SQL测试
数据库设计的三范式
第一范式:要求数据表中的字段(列)不可再分
以下表不满足第一范式(在数据库中创建不出不满足第一范式的表)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IYE3C3eX-1660738943047)(day27-mysql.assets/clip_image002.png)]
将细分的列作为单独的一列:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hBMzLHVK-1660738943047)(day27-mysql.assets/clip_image004.png)]
第二范式:不存在非关键字段对关键字段的部分依赖
以下表不满足第二范式
学号、课程编号,是这张表的联合主键,我们把学号、课程编号称为关键字段
除了关键字段之外的其他字段称为非关键字段
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3xn1kFXK-1660738943048)(day27-mysql.assets/clip_image006.png)]
将每个关键字段列出来,关键字段的组合也列出来,依次检查每个非关键字段
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LygIjd4k-1660738943048)(day27-mysql.assets/clip_image008.png)]
第三范式:不存在非关键字段之间的传递依赖
以下数据表不满足第三范式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3j655oxe-1660738943049)(day27-mysql.assets/clip_image010.png)]
将关键字段和被依赖的非关键字段分别作为主键,依次检查所有的非关键字段的依赖关系
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2qCdiBhz-1660738943049)(day27-mysql.assets/clip_image012.png)]
-1660738943047)]
第二范式:不存在非关键字段对关键字段的部分依赖
以下表不满足第二范式
学号、课程编号,是这张表的联合主键,我们把学号、课程编号称为关键字段
除了关键字段之外的其他字段称为非关键字段
[外链图片转存中…(img-3xn1kFXK-1660738943048)]
将每个关键字段列出来,关键字段的组合也列出来,依次检查每个非关键字段
[外链图片转存中…(img-LygIjd4k-1660738943048)]
第三范式:不存在非关键字段之间的传递依赖
以下数据表不满足第三范式
[外链图片转存中…(img-3j655oxe-1660738943049)]
将关键字段和被依赖的非关键字段分别作为主键,依次检查所有的非关键字段的依赖关系
[外链图片转存中…(img-2qCdiBhz-1660738943049)]
MySQL多表联查常用函数数据库设计规范相关推荐
- web mysql 界面表命名规范_MySql数据库表字段命名及设计规范
1.设计原则 1) 标准化和规范化web 数据的标准化有助于消除数据库中的数据冗余.标准化有好几种形式,但 Third Normal Form(3NF)一般被认为在性能.扩展性和数据完整性方面达到了最 ...
- mysql水平拆分 hash_常用的数据库表水平拆分方案
常用的数据库表水平拆分方案 发布时间:2018-09-28 17:50, 浏览次数:391 一,用户中心,以用户数据为例 User(uid, login_name, passwd, sex, age, ...
- mysql多表联查分页_sqlserver多表联合查询和多表分页查询的代码讲解
sqlserver多表联合查询和多表分页查询的代码讲解 发布时间:2020-05-14 14:42:07 来源:亿速云 阅读:700 作者:Leah 这篇文章主要为大家详细介绍了sqlserver多表 ...
- oracle sql now函数,SQL Server,MySQL,Oracle,PostgreSQL中常用函数用法(1)日
练习使用Hibernate没有用MySQL数据库,而是用了前不久接触的PostgreSQL,由于不同的数据对于相同的操作有各自的函数,MySQL的date_format(),在PostgreSQL中是 ...
- MySQL十表联查快速得到结果_MySQL 多表联查
1. 多表联查心德 # 1. 分析需求 # 2. 确定表与表的关联做为判断条件 # 3. 确定每表要获取的数据 # 4. 查找所需的表内容加上条件 2. 查询练习 #1.查看表结构 mysql> ...
- mysql多表联查的几种方法_多表联查的几种方式
有如下两张表 mysql> select * from teacher; +------+-----------+ | t_id | t_name | +------+-----------+ ...
- 【MYSQL快速入门】常用函数:文本函数
示例表department: 常用文本处理函数: 函数 说明 left 返回串左边的字符 length 返回串的长度 lower 将串转换为小写 upper 将串转换为大写 ltrim 去掉串左边的空 ...
- 增大mysql修改表空间_扩充数据库表空间
ALTER TABLESPACE ADD DATAFILE , [REUSE] NEXT MAXSIZE <>中是你要填的内容,有|是选其一. 如:增加文件是d:\dbfs\mydatab ...
- Mysql 多表联查索引失效问题
问题:mysql cpu占用率100%,然后查看了一下sql 四表联查一张表进行了全盘检索 找了很久,结论是其他三个表的关联字段的字符集是utf8.一张表的关联字段的字符集是utf8mb4 把关联字段 ...
- mysql 多表联查_MySQL的多表联查
今天是周二,我们一起来研究下MySQL的多表联查啊.或许你也知道,表之间的关系有:1对1.1对多.多对多.然后...... 1. 嵌套查询:一个查询的结果是另外sql查询的条件 如:查询stu表中年龄 ...
最新文章
- 和12岁小同志搞创客开发:手撕代码,做一款遥控灯
- bug诞生记——const_cast引发只读数据区域写违例
- 保存一下dedecms数据库表和字段说明,方便日后查询
- 如何解决JAVA环境变量配好后,重启电脑又失效的问题
- python import 类 继承_python学习之类的继承
- java开发第一天上班_从第一天开始,如何成为一名优秀的团队合作伙伴,成为初级开发人员
- 企业巧妙运用飞秋提高工作效率
- mha数据备份_MySQL备份与恢复之保证数据一致性(5)
- GPU与CPU的区别
- 星星之火-19:手机如何与基站进行时钟同步、时隙同步?
- virtualbox安装时发生致命错误的解决方法
- OSTEP-MLFQ(多级反馈队列)-HOMEWORK(simulation)
- 计算机视觉缺陷检测定会,视觉表面缺陷检测主要问题和发展趋势
- 三星Q90R全景声回音壁评测(首发)转自avforums
- .hdu4288 Coder CF85-DSum of Medians
- 群晖上NVMe实测兼容机型
- python大数据作业六画一个蛋糕
- [Web前端工具篇]Sublime 3安装Markdown插件
- strings命令用法
- [HDCTF2019]Maze 题解