美文网首页
SQL学习九、子查询

SQL学习九、子查询

作者: 沐左 | 来源:发表于2018-10-11 17:08 被阅读0次

    子查询:嵌套在其他查询中的查询。

    例如,我们需要获取国家内业图斑中图斑面积大于10亩的的图斑的所有附件数量

    查询

    • [1、获取图斑面积大于10亩的国家内业图斑的图斑编号
    select TBBH 
    From SURVEY_RECORD 
    Where TBMJ > 10 and TBLX = 'GJNYTB'
    
    查询结果
    • 2、根据[1]中的图斑编号去附件表中获取相关的附件数量
    select count(*) As FJ_AMOUNT
    From WYHCFJ
    where TBBH in (5668,5679,5640,5535,5502,5467,5327,5259) and TCBM = 'GJNYTB'
    
    查询结果

    子查询

    将[1]中的SQL语句作为[2]中SQL语句的子查询

    select count(*) As FJ_AMOUNT
    From WYHCFJ
    where TBBH in (
        select TBBH 
        From SURVEY_RECORD 
        Where TBMJ > 10 and TBLX = 'GJNYTB'
    ) and TCBM = 'GJNYTB'
    
    查询结果

    在 SELECT 语句中,子查询总是从内向外处理。所以上面这条SQL会先执行[1]中的SQL语句获取图斑面积大于10亩的国家内业图斑的图斑编号,然后将结果以 IN 操作 符要求的逗号分隔的格式传递给外部查询的 WHERE 子句

    包含子查询的 SELECT 语句难以阅读和调试,它们在较为复杂时更是 如此。如上所示,把子查询分解为多行并进行适当的缩进,能极大地 简化子查询的使用。


    使用子查询时需要注意的问题

    如果多个查询语句中有相同的列名时,我们需要使用完全限定列名,当表名过长的时候我们也可以使用表的别名来限定列名

    • 完全限定列名
    select count(*) As FJ_AMOUNT
    From WYHCFJ 
    where WYHCFJ.TBBH in (
        select SURVEY_RECORD.TBBH 
        From SURVEY_RECORD
        Where SURVEY_RECORD.TBMJ > 10 and SURVEY_RECORD.TBLX = 'GJNYTB'
    ) and WYHCFJ.TCBM = 'GJNYTB'
    
    • 使用别名
    select count(*) As FJ_AMOUNT
    From WYHCFJ As W
    where W.TBBH in (
        select SR.TBBH 
        From SURVEY_RECORD AS SR
        Where SR.TBMJ > 10 and SR.TBLX = 'GJNYTB'
    ) and W.TCBM = 'GJNYTB'
    

    查询的结果是一样的。


    使用计算字段

    例如,我们需要获取国家内业图斑中图斑面积大于10亩的的图斑分别拥有的附件数量

    SQL[0]:

    //执行1次子查询
    select W.TBBH, count(*) As FJ_AMOUNT
    From WYHCFJ As W
    where W.TBBH in (
        select SR.TBBH 
        From SURVEY_RECORD AS SR
        Where SR.TBMJ > 10 and SR.TBLX = 'GJNYTB'
    ) and W.TCBM = 'GJNYTB'
    group by W.TBBH
    
    查询结果

    在子查询中使用计算字段

    例如,我们需要获取国家内业图斑中图斑面积大于10亩的的图斑分别拥有的附件数量
    SQL[1]:

    //执行8次子查询
    select SR.TBBH, (
        select count(*) 
        from WYHCFJ AS W 
        Where W.TCBM = SR.TBLX and W.TBBH = SR.TBBH
        ) As FJ_AMOUNT
    from SURVEY_RECORD AS SR 
    Where SR.TBMJ > 10 and SR.TBLX = 'GJNYTB'
    order by SR.TBBH
    
    查询结果

    通过查询消耗的时间我们可以看到,查询出相同的结果,不同的SQL的查询效率是大不相同的。


    SQL执行分析

    首先,我们需要知道 SQL SELECT语句完整的执行顺序:
      1、FROM子句组装来自不同数据源的数据;
      2、WHERE子句基于指定的条件对记录进行筛选;
      3、GROUP BY子句将数据划分为多个分组;
      4、使用聚集函数进行计算;
      5、使用HAVING子句筛选分组;
      6、计算所有表达式;
      7、使用ORDER BY对结果进行排序。

    通过2和4我们基本就可以分析出上述两个SQL语句的优劣了,(WYHCFJ表比SURVEY_RECORD表数据量大)

    SQL[0]: 外部查询先执行where 子句,where子句中的子查询先在在SURVEY_RECORD表中查询(缩小数据范围),再使用Where SR.TBMJ > 10 and SR.TBLX = 'GJNYTB'作为条件查询(进一步缩小查询的范围),最终将子查询中获取到的TBBH置于外部查询的in关键字中,并以聚合函数再外部查询中进行数据统计以得到需要的结果。

    SQL[1]:将子查询置于聚合函数中,该子查询对检索出的每个TBBH都需要执行一次, 即需要执行79次,每次取一个SURVEY_RECORD表中的TBBH和TBLX到 WYHCFJ表中去进行比对,将符合条件的数据用聚合函数统计上。

    高效查询---1、是数据范围筛选合理;2、查询执行次数少

    相关文章

      网友评论

          本文标题:SQL学习九、子查询

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