子查询:嵌套在其他查询中的查询。
例如,我们需要获取国家内业图斑中图斑面积大于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、查询执行次数少
网友评论