美文网首页PL/SQL
SQL进阶之疯狂的子查询

SQL进阶之疯狂的子查询

作者: 小马过河R | 来源:发表于2020-07-06 09:36 被阅读0次

    今天我们不谈子查询的执行效率,只谈子查询功能。对于SQL语句来说,编程开发人员应该都不会陌生,其实各种复杂的逻辑最终落地也就是那么几个基本的招式,增删改查,然而我们经常听到武功招式中又各种连招,那就是了,子查询就是这么个意思。很多SQL简单查询完成不了的查询,子查询都可以很疯狂地完成。当然有的需要一个子查询就够了,有的甚至可能需要嵌套多个子查询来完成。

    场景再现

    废话不多说,我们来感受一下一个场景。假设我现在想查询一个表的重复数据,也就是我们经常所说的查询有重复记录的数据,那我该如何写语句呢?

    查询含有重复项的数据

    以上语句,having一般和group by一起用,本语句是先分组,对每组结果各自进行count(user_id)。那再试想一下,那如果我想要去重,找到ID较小的那条记录展示并用于后续执行删除呢?是不是就要子查询帮忙了。答案是肯定的。子查询可以解决简单查询无法完成的复杂逻辑查询,小马曾经就写过上百行的一个SQL查询语句,当然这是不被建议的,只是当时数据表设计的缺陷问题,不得已而为之,也算是权宜之计。那么子查询到底能多疯狂呢?下面就一起来感受一下。

    什么是子查询

    什么是子查询?这里我们可以通俗地理解为,子查询就是将一个查询(子查询)的结果作为另一个查询(主查询)的数据来源或判断条件的查询。这句话很好理解,就是有一个子查询被作为另一个主查询的数据来源判断条件。常见的类型有WHERE子查询,HAVING子查询,FROM子查询,SELECT子查询,EXISTS子查询。

    首先我们来创建一个表结构student表,然后插入若干数据。

    student表结构

    下面我们就来看看这几种类型的不同应用。

    五种类型的子查询

    上面是按照五种类型以此展示的含子查询语句案例。第一个查询语句取分数低于平均分的学生;第二个查询语句取平均分+20能大于最高分的职位并同时输出其平均分是是多少;第三个查询语句查询平均分数高于25的职位以及显示该职位的平均分数;第四个查询语句查询职位是组长的学生人数占总学生人数的比例;第五个查询语句查询有住宿信息的学生。怎么样,子查询是不是很万能,感受到它的疯狂了吗?这里只是简单的示例,当然还能根据业务组合出更加复杂的查询逻辑。

    以下附上上面5个语句查询的结果展示。

    WHERE子查询 HAVING子查询 FROM子查询 SELECT子查询

    项目实战

    练兵之后,我们就该上实际项目实践以下了。来实战一个比较复杂的需求:我现在有一个分享功能,DB需要记录用户每次的分享详细数据,如果用户当天有分享则可以结算一次积分,注意每天可以分享无限次但只能结算一次。于是我们的DB设计:

    tbShare表

    现在我们的需求来了,我想查询用户openid为1的每日分享结算情况?怎么查询呢?

    那如果要获取已结算的总数或者总天数呢?

    我想要查询用户openid为1的一条最早的未结算的分享数据来进行结算,怎么取呢?

    好了,是不是已经掌握到技巧了,其实万变不离其宗。我们说其实子查询语句的效率不一定就好,那么假如不需要用户具体的每日分享详细时间数据,只需要知道每日分享总次数,我们可以怎么改造DB设计使其避免进行子查询呢?以下是改造后的DB供参考,至于为什么更好呢,改造后逻辑又是怎么实现,可以先自行思考哈。

    关于SQL语句的子查询就到这了,欢迎评阅和交流。

    原创文章,未经允许请勿转载。

    相关文章

      网友评论

        本文标题:SQL进阶之疯狂的子查询

        本文链接:https://www.haomeiwen.com/subject/tgziqktx.html