各位老铁们好,相信很多人对常用SQL系列(三):记录叠加、匹配、外连接和笛卡尔等都不是特别的了解,因此呢,今天就来为大家分享下关于常用SQL系列(三):记录叠加、匹配、外连接和笛卡尔等以及的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!
前两篇文章链接:
(1):SQL点滴(查询):实用数据库查询案例
(二):SQL点滴(排序篇):数据常规排序查询实战示例
(17)如何实现多表记录的叠加返回?
也就是如何将多个表的数据组织在一起,并叠加各个表的结果。这些表的关键字不一定相同,但每个表中对应列的数据类型应该相同。例如,我们有部门号为2的所有员工的姓名和编号,以及部门的姓名和编号。实现参考SQL如下: select ename, emid fromEmployee where Departid=2union allselect ‘———— ‘, nullunion allselect dpname,dpid from Department 中间的select 横线是可选的指示多个表之间结果的分离。关键是使用union all来实现多表结果的叠加返回。所以可能会出现重复的结果。如果要重复结果,可以使用distinct 将子查询应用于结果。
(18)如何基于关联列把不同表列值组合到一行返回?
也就是说,通过关联列(多为外键),将不同表的行、行值累加到另一个表的行、行值,并作为一行返回(如果多行满足条件下,将返回多行)。我们以员工和部门为例,实现相关的行组合来显示员工姓名、工资、部门名称和地址。 SQL 示例如下: select ename,salary,d.dpname,d.dpaddress from employee e,tx_department d 其中e.departid=d.dpid 实际上是数据库关联查询的内连接,相当于以下查询:相关列。还有另一种编写内连接的方法。参考如下: select ename, salary, d.dpname, d.dpaddress from employee e inner join tx_department d on e.departid=d.dpid。难道就不能等吗?
(19)如何在两个表中查找共同行?
也就是说,是A表和B表。存在一种情况,A表中的行值包含在B表中的行值中(相当于B表中的行值的子行) ,比如员工表和团队表包含人员的姓名、职位和部门ID,员工表包含团队表中的信息。如何返回团队的所有信息以及员工的工资和人数信息?我们可以这样写SQL,参考如下: select e.eid,e.ename,e.job,e.salary,e.departid from employee e, team twhere e.ename=t.ename and e.job=t。 job 和e.departid=t.departid 这样就可以达到我们想要的结果了。当然,你可以参考我们之前的例子(SQL技巧(18):如何将不同的表列值组合成一行,并根据关联列返回?也就是说,通过关联列(大多是国外的)键),可以组合不同表的行和列值,累了.),把上面的语句改成join子句的形式。尝试一下。
(20)如何从一个表中查找另一个表中没有的值?
即从一个(称为数据源)中查找另一个目标表中不存在的值。例如,从部门表department中查找员工表employee中没有数据的所有部门(相当于说,如果部门表有10条记录,而员工表中的部门只使用了不到10个部门,则有将不会使用部门来查找)。不同的DB针对这个问题有不同的解决方案。例如,DB2、PostgreSQL和Oracle支持差异集操作,但MySQL和SQL Server不支持。因此,在MySQL中,我们使用子查询来实现。参考示例如下:select Dedeid from Department where DedeId not in (select DedeId from Employment)。这句话也适用于SQL Server。那么,在支持差异集操作的Oracle中,可以这样实现:selectdepartidfromdepartment减去selectdepartidfromemployee即可达到我们想要的效果。如果是DB2或PostgreSQL,只是区别关键字不同,只需将minus替换为except 即可。但需要注意的是,在except/减差操作中,两个选择列表中值的数量和数据类型必须匹配,并且except 不会返回重复行。含义是返回上一个查询结果中不在后续查询结果中的所有行。
(21):如何利用外连接在一个表中查找与其它表不匹配的记录?
例如有一个场景,部门表中使用了8个部门,但员工表中只关联了6个部门。如何利用外部联系找到没有员工的部门?我们可以这样做: select d.* from Department d left external join employee e on (d.departid=e.departid) ,其中e.departid 为null 。这样我们就可以找到所有没有员工的部门。上述SQL适用于MySQL、BD2、SQL Server和PostgreSQL。如果是Oracle 9i及以后版本,上面的写法也适用。还可以使用Oracle特有的外连接语法(+),如:select d.* from Department d,employee e where d.departid=e.departid (+) and e.departid is null。尝试一下。
(22):有3张关联表,如何基于前两表的全关联附加第三张表部分关联信息 ?
场景可以描述为:部门表、员工表和员工奖励表,则返回所有员工的姓名和部门,并关联显示部分已奖励员工的奖励日期(不是所有员工都得到奖励,只有少数吧)。我们可以这样编写SQL 语句: SELECTe.ename,d.dpname,b.receivedFROMemployee e JOIN Department dON (e.departid=d.dpid)left join ebonus bon (e.emid=b.emid)order by 2。结果见下图。顺便问一下:如果只返回上述有奖励的员工信息,这条SQL语句该如何重写呢?尝试一下吧^_^
(23):多表查询时笛卡儿积及处理规则是怎样的?
场景如下。部门表中有4条记录,员工表中有部门2的3条记录。如果我们这样查询,将生成笛卡尔积: SELECTe.empname,d.dpnameFROMemployee e,depart dWHEREe .dpid=2ORDER BY 1 的结果将返回12 条记录,这显然不是笛卡尔积的预期结果。这里笛卡尔积的原因类似于从A经B到C,分为2步。从A到B有3种方式,从B到C有4种方式,最终A到C有3*4=12种方式。如果表中的查询按照这种无约束执行来执行,就会产生笛卡尔积。因此,一般来说,要避免笛卡尔积,需要使用n-1规则,n是from之后的表数,n-1是避免笛卡尔积的最小连接数。根据表中的关键字和相关列,可能需要超过n-1 个联接。如何纠正上述SQL 语句以避免笛卡尔积?根据规则,可以是这样的: SELECTe.empname,d.dpnameFROM员工e,depart dWHERE e.dpid=2 and e.dpid=d.dpidORDER BY 2。就这样了。尝试一下,关键是理解上面的规则。
(24):聚集于外连接时的重复计算问题
场景是这样的,即统计2部门员工的工资总额和奖金总额(主键值)。这里假设每个员工的工资是固定的,但是可以有多个奖励记录。假设员工abc有两条奖励记录。我们第一次写统计SQL是这样的: select Departid,sum(salary) astotal_sal, sum(bonus)astotal_bonusfrom (select e.emid,e.ename,e.salary,e.departid,e.salary* case when eb.types=1 then .1when eb.types=2 then .2else .3 end as BonusfromEmployee e, ebonus ebwhere e.emid=eb.emid and e.departid=3 ) s group by Departid SQL 查询结果如图1所示。这个结果是部分错误的,奖励总额是正确的,但工资总额是错误的。原因是在子查询中再次计算了abc员工的工资。单独执行from子查询的结果如下图二所示。即李可有两次打赏记录,统计汇总时多计算一次。如何纠正呢?只需更正我们开始编写的SQL,如下所示: select Departid,sum(DISTINCT salary) astotal_sal,sum(bonus)astotal_bonusfrom (select e.emid,e.ename,e.salary,e.departid,e.salary * case当eb.types=1 then .1当eb.types=2 then .2else .3 作为员工e 的奖金结束left external join ebonus eb on ( e.emid=eb.emid)where e.departid=3 ) s group by Departid这样就得到了正确的结果,如图3所示。 好吧,这里需要注意的是distinct在外连接和聚合函数中的应用。自己尝试一下。 ^_^
原创文章,作者:小su,如若转载,请注明出处:https://www.sudun.com/ask/203488.html
用户评论
话少情在
看了教程以后感觉对SQL操作数据理解更深了!record叠加和匹配简直太有用,之前经常在这两方面犯错。感谢作者分享这些实用技巧!
有6位网友表示赞同!
落花忆梦
笛卡尔积一直是我头疼的问题,这个教程解释得非常清晰,这下终于明白了它的原理和使用方法,以后可以用这种方法解决很多数据分析问题了!
有6位网友表示赞同!
念安я
外连接的使用很常用,但是我经常搞混它和其他连接的用法。还好这个教程讲解得很详细,现在终于清楚了它们的区别。希望后续还会有更多关于SQL高级查询的教程。
有11位网友表示赞同!
醉婉笙歌
文章内容确实很棒,对理解这几种sql操作很有帮助。不过感觉有些地方的例子太简单,希望能有更复杂的操作场景进行演示,这样会更有实战意义。
有15位网友表示赞同!
雁過藍天
作者你真是太好了呀!终于有人详细解释了这些常用的SQL方法。之前我总是看博客或者论坛就只懂皮毛,现在有了这个教程真的一举顿悟了!
有20位网友表示赞同!
╭摇划花蜜的午后
匹配和叠加操作确实有用的场景,但我觉得这些方法在实际应用中经常会带来性能问题,尤其是在数据量很大的时候。文中是否能考虑补充一些针对性能优化的技巧?
有16位网友表示赞同!
铁树不曾开花
这篇文章写的真好理解,我刚开始学SQL,以前觉得SQL操作数据的难度很大,看完这个教程,感觉很多难题都能解决了!
有8位网友表示赞同!
烬陌袅
笛卡尔积我一直以为是某种高级数据库概念,没想到这么简单!希望以后能学习更多的SQL技巧,把自己的数据分析能力提升上去!
有20位网友表示赞同!
酒笙倾凉
记录叠加这种方法很有趣,以前我都是一个个字段累加,效率太低了。用这个方法可以大大简化代码,提高执行速度!
有14位网友表示赞同!
心已麻木i
我觉得这篇文章的例子和讲解都很清晰易懂,对于初学者来说非常友好!希望作者继续更新更多关于SQL的文章,帮我们深入学习数据库管理。
有14位网友表示赞同!
有恃无恐
虽然文章讲得很清楚,但我还是觉得外连接的操作比较复杂,需要多加练习才能熟练掌握. 希望能提供一些更复杂的例子,帮助我更好地理解和应用。
有8位网友表示赞同!
生命一旅程
我感觉这个教程更偏向于基础操作的讲解,对于进阶用户来说可能不够深入。希望后续可以讲些更高级的合计方法、子查询等内容。
有12位网友表示赞同!
屌国女农
记录叠加太酷了!感觉以前浪费了那么多时间去做那些重复性的计算。这个技巧要好好学习一下,以后用SQL处理数据会更快更高效!
有11位网友表示赞同!
箜明
这篇文章讲解的很全面,所有常用的 SQL 操作 都详细介绍了. 特别是匹配和外连接的解释非常清晰,对我提高SQL操作能力很有帮助!
有14位网友表示赞同!
孤者何惧
笛卡尔积这个概念确实很抽象,还好作者用通俗易懂的例子进行说明,让我能够更好地理解它的原理。
有19位网友表示赞同!
强辩
这篇文章对学习数据库管理非常有用,感谢作者分享这些宝贵的知识!希望以后能继续学习更多的SQL操作技巧,提升自己的技能等级!
有12位网友表示赞同!
赋流云
文章内容实用性很高,讲道理外连接一直是我在用的SQL中最困惑的, 终于搞明白了!记录叠加这个方法以前也没见过, 看例子也很简单易懂,可以去试一下。
有5位网友表示赞同!
素婉纤尘
个人对教程里的一些解释还有疑问,比如文章提到匹配和叠加操作可能带来性能问题,但我想了解这样的问题应该如何优化,能不能在文中提供一些解决方案或者建议?
有17位网友表示赞同!
遗憾最汹涌
感觉文章结构很清晰,内容也很全面,学习这部分SQL知识太容易了! 希望作者后续可以分享更多关于数据分析的技巧,帮助我们更好地利用SQL进行数据库操作。
有14位网友表示赞同!