| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> 五分钟了解SQL进阶查询 -> 正文阅读 |
|
[大数据]五分钟了解SQL进阶查询 |
目录 一、数据库约束(Foreign Key Constraint) ?三、联合查询/多表查询(Associated Query) 一、数据库约束(Foreign Key Constraint)约束类型:
其他的都比较常见,也比较好理解,这里主要介绍一下外键约束。 外键用于关联其他表的主键或唯一键。 语法:foreign key (字段名) references 主表(列) 1、NO ACTION案例: 1.创建班级表classes,id为主键: ? ?2.创建学生表stuents,一个学生对应一个班级,一个班级对应多个学生。使用sid为主键, ? ?建立学生表的外键关系时,给右边Options选项改为NO ACTION ? ?建表完成后再去插入语句,然后我们尝试去删除班级表中的记录,这时我们会发现,无论选择用DELETE、TRUNCATE还是DROP方法,都无法删除班级表中跟约束有关的记录。外键约束在这里的作用是没有删除学生表中的记录就不允许删除班级表。 ? ?2、SET NULL还是以上面两个表为例,先建立好班级表,然后建立学生表的时候使用cai作为外键,右侧的Options选择SET NULL。注意,这里学生表的cid要允许为空,因为SET NULL之后删除班级表的cid字段学生表的cid会置为空,如果不允许为空就会报错。 这里只放学生表截图了,班级表同上 ? ?? ?这时我们执行DELETE语句删除班级表就不会报错了。SET NULL可以允许班级表的外键字段为空,也就是删除了,随之学生表的cid字段也都会置为空。 ?? ?3、CASCADE以NO ACTION的表为例,首先建立班级表,和上面的一样,这里就不再多说了,然后建立学生表时只需要将右边的Options改为CASCADE就可以了。 ? ?此时我们再执行语句delete from classes where cid = 1;删除班级表的cid,就会发现班级表的相关字段和学生表的相关字段都被置为空,可以和上面的SET NULL 做对比。 ?? ?可以很明显发现两者区别。 总结:无论哪种策略,drop班级表都无法成功,必须先drop学生表才能drop学生表,外键策略主要影响的是update、delete。第一种NO ACTION不允许delete或者update,第二种SET NULL 和第三种CASCADE都允许delete删除班级表的cid,SET NULL 会把学生表的cid置为null,CASCADE会把对应的学生记录删除。 二、聚合查询(Aggregation Query)1、聚合函数?常见的统计数据、计算平均值操作都可以通过聚合函数来实现。常见的聚合函数有: ?
?
?
?
?
? 2、GROUP BY 子句?SELECT 中使用 GROUP BY 子句可以对指定列进行分组查询。需要满足:使用 GROUP BY 进行分组查询时,SELECT 指定的字段必须是“分组依据字段”,其他字段若想出现在SELECT 中则必须包含在聚合函数中。 语法:? ?聚合查询时,SELECT子句只能出现两种内容:1、分组依据(group by后面的字段) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2、聚合函数(count...) 举例说明1:现有如下表 ? ?若要查询一个班级的每个科目成绩最高的分数,则语句应为 SELECT 科目,max(成绩) FROM 成绩表 GROUP BY 科目; 得到的结果应该是这样: ? 举例说明2: 准备测试表及数据:职员表,有id(主键)、name(姓名)、role(角色)、salary(薪水) 建表如下: ? ?现在要查询每个角色最高工资、最低工资、平均工资。语句如下: SELECE role,max(salary),min(salary),avg(salary) FROM 职员表 GROUP BY role; 这里也可以起别名、排序... SELECT role, max(salary) max_salary,avg(salary) avg_salary ?from emp GROUP BY role ORDER BY ?max_salary DESC; 执行结果如下: ? ?3、having 聚合后再过滤GROUP BY 子句进行分组以后,需要对分组结果再进行条件过滤时,不能使用 WHERE 语句,而需要用HAVING。 现在要查询平均工资大于600的角色以及这个角色的最高薪资 SELECE role,max(salary) max_salary,avg(salary) avg_salary FROM 职工表 GROUP BY role ?HAVING avg_salary >= 600 ORDER BY avg_salary DESC;? 执行结果如下: ? ?三、联合查询/多表查询(Associated Query)实际开发中往往数据来自不同的表,所以需要多表联合查询。多表查询是对多张表的数据取笛卡尔积。 联合查询优点:降低了数据的冗余,提升了操作的便利性。 缺点:增加了查询的复杂性。
? 举例说明:现在有班级表和学生表,学生所属不同班级,现有如下语句: SELECT * FROM 班级表,学生表; ? ?那么查询记录应该有几条呢?答案是4*7=28条。 这里可以用SELECT COUNT(*) FROM class,student;来验证一下 ? 1、内连接(inner join)?笛卡尔积给出了28行结果,而我们查询学生所在的班级,真正想要的只有七行结果,所以我们现在的目标是从28行中过滤出有效的7行记录。这里就可以使用where语句进行过滤。 SELECT c.cid,c.name,sid,s.name from class c,student s where c.cid = s.cid; 这里我们使用的是别名,因为班级表和学生表的cid字段有歧义,使用别名加以区分。 查询到的结果如下: ? 为了更好地理解内联,这里我们换个语法来讲。 SELECT?c.cid,c.name,sid,s.name FROM class c join student s on c.cid = s.cid; 这里得到的结果和上面的是一样的。但是我们现在的表体现不出来内联的效果,当我们在班级表增加一个没有学生的班级,在学生表添加一名班级cid不存在的学生,内联的效果就能体现出来了。具体的可以参考下面的外连接。 可以看到,语法中是class join student ,班级链接学生表,这里我们以班级为左表(主表),学生为右表。内连接相当于左右表的并集。查询范围是左表和右表的公共部分。 ? 所以当表为这样的时候: ?? ?班级表有些班级没有学生,学生表中有的学生对应的班级id不存在。如cid为105的班级和sid为8的学生。 执行上述语句出现的结果还是会一样。 ?2、自连接自连接是指在同一张表连接自身进行查询。 自己和自己联合,要求至少给一个表起别名,因为字段有歧义。 如:SELECT * from class c,class t; 两张表都是班级表上做联合查询。 举例:这里建立一张带有学生和班长的学生表。 ?? ?现在要查找出学生的id+其班长的id: ?SELECT s.name stu,t.name leader FROM?students_with_leader s,students_with_leader t WHERE s.sid = t.leader_id; 得到执行结果:每个学生对应自己班长。这里班长可以理解为组长,我就不再改了。 ? ?这里也可以用 join on 语法写。具体语法如下: SELECT s.name stu,t.name leader FROM students_with_leader s join students_with_leader t on s.leader_id = t.sid; 这样写和上面拿到的结果是相同的,FROM后面跟的是表名称,可以认为s是主表,join后面的t是副表,两个表都是由students_with_leader引申出来的,然后再做联合查询。但是一定要注意别名,别名字这里很重要,用以区分两张表有歧义的部分。 3、外连接(outer join)外连接分为左外连接和右外连接。如果联合查询,左侧的表完全显示我们就说是左外连接;右侧的表完全显示我们就说是右外连接。 这里我们还是以班级表和学生表为例。 班级表有些班级没有学生,学生表中有的学生对应的班级id不存在。如cid为105的班级和sid为8的学生。 ?? ????????1> 左外联左外联以左表为主,即查询范围为有班级没学生和有班级有学生。 ? ?当我们执行如下语句的时候,会看到这样的结果: SELECT * FROM class c left outer join student s on c.cid = s.cid; ?当然,这条语句如果去掉outer结果是一样的,上面语句等同于这条语句: SELECT * FROM class c left join student s on c.cid = s.cid; ????????2>右外联右外联以右表为主,即查询范围为有班级有学生和有班级没学生 ? ?现执行右外联语句: SELECT * FROM class c right outer join student s on c.cid = s.cid; 得到如下结果: ? ?同样,语句这样写也可以: SELECT * FROM class c right join student s on c.cid = s.cid; ????????3>全外联全外联,顾名思义,左表右表都包括在查询范围内。 ? ?MySQL暂时不支持全外联查询,这里就不做演示啦。 小结:只有两张表数据对不上时,区分内联外联才有意义。内联相当于左表右表的并集,左外联包括整个左表相关的记录,右外联包括整个右表相关的记录。 在语法上,join后面接连接的表名,on后面接条件。 4、子查询(subquery)5、合并查询子查询和合并查询我们下次讲吧...太累了 求个赞.. 注:文章有参考比特课件和老师板书 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/28 2:10:44- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |