SQL学习九、子查询

2018-10-11  本文已影响0人  沐左

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

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

查询

select TBBH 
From SURVEY_RECORD 
Where TBMJ > 10 and TBLX = 'GJNYTB'
查询结果
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、查询执行次数少

上一篇下一篇

猜你喜欢

热点阅读