sql语句的执行顺序是啥,为啥下面这两个sql执行的结果是一样的

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql语句的执行顺序是啥,为啥下面这两个sql执行的结果是一样的相关的知识,希望对你有一定的参考价值。

我把条件放到having后面和放到select中效果是一样的,但是想不明白这个执行顺序是什么样的,请大神帮我看看,谢谢

1、select ssjgm,shbh,shmc,ylzd6,jyrq,chzh,lsbh,if (right(jym,1) in (1,4),'借记','贷记') as jdj,if(jyqd=1,'本行','他行') as jylx,sapbh,sapmc,jyje/100,shsxf/100 from bs_jylsls_08 where jyrq like '2018%' and shbh in
(
select shbh from
(
select shbh,shmc,sum(jyje)/100 as hzje, sum(case when right(jym,1) in(2,8) then jyje else 0 end)/100 as ljje
from bs_jylsls_08 where
jyrq like '2018%' and jyztm='00' and hclzt='00'
and jyje>0
and sapbh in('500024','500034','500047')
group by shbh having ljje >= 50000 and ljje/hzje >='0.8'
) as lsb
)
and jyje>0 and jyztm='00' and hclzt='00'
and sapbh in('500024','500034','500047') ;

2、select ssjgm,shbh,shmc,ylzd6,jyrq,chzh,lsbh,if (right(jym,1) in (1,4),'借记','贷记') as jdj,if(jyqd=1,'本行','他行') as jylx,sapbh,sapmc,jyje/100,shsxf/100 from bs_jylsls_08 where jyrq like '2018%' and shbh in
(
select shbh from bs_jylsls_08
where
jyrq like '2018%' and jyztm='00' and hclzt='00'
and jyje>0
and sapbh in('500024','500034','500047')
group by shbh having sum(case when right(jym,1) in(2,8) then jyje else 0 end)/100>='50000'
and sum(case when right(jym,1) in(2,8) then jyje else 0 end)/sum(jyje)>='0.8'
)
and jyje>0 and jyztm='00' and hclzt='00'
and sapbh in('500024','500034','500047')

你这两个sql语句只是运行顺序不同
第一个sql语句你嵌套多一层子查询,先把sum(case when right(jym,1) in(2,8) then jyje else 0 end)/100 两个聚合函数算出来,然后在分组having直接过滤。
而第二个sql是在having的时候才去算sum(case when right(jym,1) in(2,8) then jyje else 0 end)/100 两个聚合函数的值。
但是你最后都是用这个条件去过滤的,所以结果是一样的
参考技术A 本来就一样的啊。你第一次是先select bs_jylsls_08 想要的数据,定位为 lsb 这个别名,然后再 IN shbh ,但不会影响 后面附加的查询,第二个你直接查询 后 bs_jylsls_08 in shbh
两个差异就在有没有一个 lsb 别名 而SQL server 的优先级是:
1. FROM:对FROM子句中前两个表执行笛卡尔积生成虚拟表vt1
2. ON: 对vt1表应用ON筛选器只有满足 join_condition 为真的行才被插入vt2
3. OUTER(join):如果指定了 OUTER JOIN保留表(preserved table)中未找到的行将行作为外部行添加到vt2,生成t3,如果from包含两个以上表,则对上一个联结生成的结果表和下一个表重复执行步骤和步骤直接结束。
4. WHERE:对vt3应用 WHERE 筛选器只有使 where_condition 为true的行才被插入vt4
5. GROUP BY:按GROUP BY子句中的列列表对vt4中的行分组生成vt5
6. CUBE|ROLLUP:把超组(supergroups)插入vt6,生成vt6
7. HAVING:对vt6应用HAVING筛选器只有使 having_condition 为true的组才插入vt7
8. SELECT:处理select列表产生vt8
9. DISTINCT:将重复的行从vt8中去除产生vt9
10. ORDER BY:将vt9的行按order by子句中的列列表排序生成一个游标vc10
11. TOP:从vc10的开始处选择指定数量或比例的行生成vt11 并返回调用者
无论你是select * from a 或者 select * from(select * from a)v 只要你 where 不变,都会优先执行where 所以你 select 函数是会在你 bs_jylsls_08 的where 条件执行完再执行。然后select 后再执行 shbh in 。所以顺序一样。结果也一样

Hive SQL语句执行顺序

参考技术A

Hive 中 sql 语句的执行顺序如下:

from .. where .. join .. on .. select .. group by .. select .. having .. distinct .. order by .. limit .. union/union all

下面我们通过一个 sql 语句分析下:

上面这条 sql 语句是可以成功执行的,我们看下它在 MR 中的执行顺序:

Map 阶段

Reduce 阶段

上面这个执行顺序到底对不对呢,我们可以通过 explain 执行计划来看下,内容过多,我们分阶段来看。

我们看到 Stage-5 是根,也就是最先执行 Stage-5,Stage-2 依赖 Stage-5,Stage-0 依赖 Stage-2。

图中标 ① 处是表扫描操作,注意先扫描的 b 表,也就是 left join 后面的表,然后进行过滤操作(图中标 ② 处),我们 sql 语句中是对 a 表进行的过滤,但是 Hive 也会自动对 b 表进行相同的过滤操作,这样可以减少关联的数据量。

先扫描 a 表(图中标 ① 处);接下来进行过滤操作 idno > \'112233\'(图中标 ② 处);然后进行 left join,关联的 key 是 idno(图中标 ③ 处);执行完关联操作之后会进行输出操作,输出的是三个字段,包括 select 的两个字段加 group by 的一个字段(图中标 ④ 处);然后进行 group by 操作,分组方式是 hash(图中标 ⑤ 处);然后进行排序操作,按照 idno 进行正向排序(图中标 ⑥ 处)。

首先进行 group by 操作,注意此时的分组方式是 mergepartial 合并分组(图中标 ① 处);然后进行 select 操作,此时输出的字段只有两个了,输出的行数是 30304 行(图中标 ② 处);接下来执行 having 的过滤操作,过滤出 count_user>1 的字段,输出的行数是 10101 行(图中标 ③ 处);然后进行 limit 限制输出的行数(图中标 ④ 处);图中标 ⑤ 处表示是否对文件压缩,false 不压缩。

限制最终输出的行数为 10 行。

通过上面对 SQL 执行计划的分析,总结以下几点:

以上是关于sql语句的执行顺序是啥,为啥下面这两个sql执行的结果是一样的的主要内容,如果未能解决你的问题,请参考以下文章

sql查询语句的各个命令执行的标准顺序是啥?为啥?

Hive SQL语句执行顺序

SQL基础:语句执行顺序

如何直接执行SQL语句

SQL语句的执行顺序

SQL语句执行流程与顺序原理解析