你真的会玩SQL吗?之逻辑查询处理阶段
最近要对数据库进行优化,但由于工作项目中已经很少亲自写SQL而且用的都不是很复杂的语句,所以有些生疏了,于是翻翻N年前的笔记资料,想以此来记录回顾总结一些实用的SQL干货让大家来学习,若有不对之处可提出。
记得刚出来行走江湖的时候也是只会增、删、改、查四大法宝,一般公司没有多少复杂的业务,所以就够用了。但后来看着大神会写个几百行的SQL存储过程就感觉自己是不是弱爆了。
如今是大数据的时代,对数据的处理要求越来越重视,要出各种数据报表,因此百万数据处理速度,数据库明显比后台逻辑处理的优势不是一个别。
在此我想再次提示一个数据处理的中心思想,SQL数据处理是集合思维,不要用逻辑思维来思考。
文中的示例来自自己的积累和TSQL2008技术内幕。
基础知识普及
对于教条式的定义请自己去查,此处不会涉及到文邹邹的知识,但还是强调一下基础的重要性,即使你理解了所有的概念,但当组合起来用时也会一头雾水。
逻辑查询处理阶段
在以上的10个处理步骤中, 每一步的处理都生成一个虚拟表来作为下一步的输入. 虚拟表对于调用者或输出查询来说是不存在的, 仅在最后步骤生成的表才会返回给调用者或者输出查询. 如果某一子句没有出现在SQL语句中, 这一步就被简单跳过..
这10个具体步骤是:
1.FROM: from子句中的两个表首先进行交叉连接(笛卡尔积), 生成虚拟表VT1。
2.ON:
on条件作用在VT1上, 将条件为True的行生成VT2。
3.OUTER: 如果outer join被指定, 则根据外连接条件,
将左表or右表or多表的未出现在VT2查询结果中的行加入到VT2后生成VT3。
4.WHERE: VT3表中应用Where条件,
结果为真的行用来生成VT4。
5.GROUP BY: 根据Group by指定的列, 将VT4的行组织到不同的组中,
生成VT5。
6.CLUB|ROLLUP: 超级组(分组之后的分组)被添加到VT5中, 生成VT6。
7.HAVING: Having用来筛选组,
VT6上符合条件的组将用来生成VT7。
8.SELECT: select子句用来选择指定的列, 并生成VT8。
9.DISTINCT:
从VT8中删除重复的行后, VT9被生成。
10.ORDER BY: 根据Order by子句, VT9中的行被排序, 生成游标10。
注意事项:
第一步中FROM: 需要对两表同时存在的列添加前缀, 以免混淆.
第二步中ON: 在SQL特有的三值逻辑(true,false,unknown)中, unkown的值也是确定的, 只是在不同情况下有时为true, 有时为false. 一个总的原则是: unknown的值非真即假, 非假即真. 也就是时说, unknown只能取true和false里面的一个值, 但是unknown的相反还是unknown.如:
在ON、WHERE和HAVING中做过滤条件时, unknown看做false;
在CHECK约束中, unknown被看做是true;
在条件中, 两个NULL的比较结果还是Unknown.
在UNIQUE和PRIMARY KEY约束、排序和分组中, NULL被看做是相等的. 例如Group by 将null分为一组, 而order by将所有null排在一起.
第三步中OUTER: 如果多余两张表, 则将VT3和FROM中的下一张表再次执行从第一步到第三步的过程.
第四步中WHERE: 由于此刻没有分组, 也没有执行select所以, where子句中不能写分组函数, 也不能使用表的别名. 并且, 只有在外连接时, on和where的逻辑才是不同的, 因此建议连接条件放在on中.
第五步中GROUP BY: 如果查询中包含Group by 子句, 那么所有的后续操作(having, select等)都是对每一组的结果进行操作.
Group by子句中可以使用组函数, 在Sql 2000中一旦使用组函数, 其后面的步骤将都不能处理, 而在
Sql2005中没有这个限制.
第六步不常用, 略过.
第七步中HAVING: having表达式是仅有的分组条件. 注意: count(*)不会忽略掉null, 而count(field)会; 此外分组函数中不支持子查询做输入.
第八步中SELECT: 如果包含Group By子句, 那么在第5步后将只能使用Group By子句中出现的列, 如果要使用其他原始列则, 只能使用组函数.
另外, select在第八步才执行, 因此别名只能第八步之后才能使用, 并且只能在order by中使用.
第九步中DISTINCT: 当使用Group By子句时, 使用Distinct是多余的, 他不会删除任何记录.
第十步中ORDER BY: 按Order by子句指定的列排序后, 返回游标VC10.
别名只能在Order by子句中使用.
如果定义了Distinct子句, 则只能排序上一步中返回的表VT9, 如果没有指定Distinct子句, 则可以排序不再最终结果集中的列. 例如: 如果不加Distinct则Order by可以访问VT7和VT8中的内容.
这一步最不同的是它返回的是游标而不是表, Sql是基于集合论的, 集合中的元素师没有顺序的, 一个在表上引用Order by排序的查询返回一个按照特定特定物理顺序组织的对象—游标. 所以对于视图、子查询、派生表等均不能将order by结果作为其数据来源.
建议: 使用表的表达式时, 不允许使用order by子句的查询, 因此除非你真的要对行排序, 否则不要使用order by 子句.
内容为 RJ 写的,逻辑非常清楚,值得花点时间理解,再次强调是因为复杂的集合数据处理过程中会得到不是你想要的结果,这时就要你自己脑袋当SQL处理器来推出结果查出问题,可能大多数写了几年的SQL都还没弄明白,但到了用时还是提前理解下,非常重要。
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
持证人简介:贺渲雯 ,CDA 数据分析师一级持证人,互联网行业数据分析师 今天我将为大家带来一个关于用户私域用户质量数据分析 ...
2025-04-18一、CDA持证人介绍 在数字化浪潮席卷商业领域的当下,数据分析已成为企业发展的关键驱动力。为助力大家深入了解数据分析在电商行 ...
2025-04-17CDA持证人简介:居瑜 ,CDA一级持证人,国企财务经理,13年财务管理运营经验,在数据分析实践方面积累了丰富的行业经验。 一、 ...
2025-04-16持证人简介: CDA持证人刘凌峰,CDA L1持证人,微软认证讲师(MCT)金山办公最有价值专家(KVP),工信部高级项目管理师,拥有 ...
2025-04-15持证人简介:CDA持证人黄葛英,ICF国际教练联盟认证教练,前字节跳动销售主管,拥有丰富的行业经验。在实际生活中,我们可能会 ...
2025-04-14在 Python 编程学习与实践中,Anaconda 是一款极为重要的工具。它作为一个开源的 Python 发行版本,集成了众多常用的科学计算库 ...
2025-04-14随着大数据时代的深入发展,数据运营成为企业不可或缺的岗位之一。这个职位的核心是通过收集、整理和分析数据,帮助企业做出科 ...
2025-04-11持证人简介:CDA持证人黄葛英,ICF国际教练联盟认证教练,前字节跳动销售主管,拥有丰富的行业经验。 本次分享我将以教培行业为 ...
2025-04-11近日《2025中国城市长租市场发展蓝皮书》(下称《蓝皮书》)正式发布。《蓝皮书》指出,当前我国城市住房正经历从“增量扩张”向 ...
2025-04-10在数字化时代的浪潮中,数据已经成为企业决策和运营的核心。每一位客户,每一次交易,都承载着丰富的信息和价值。 如何在海量客 ...
2025-04-09数据是数字化的基础。随着工业4.0的推进,企业生产运作过程中的在线数据变得更加丰富;而互联网、新零售等C端应用的丰富多彩,产 ...
2025-04-094月7日,美国关税政策对全球金融市场的冲击仍在肆虐,周一亚市早盘,美股股指、原油期货、加密货币、贵金属等资产齐齐重挫,市场 ...
2025-04-08背景 3月26日,科技圈迎来一则重磅消息,苹果公司宣布向浙江大学捐赠 3000 万元人民币,用于支持编程教育。 这一举措并非偶然, ...
2025-04-07在当今数据驱动的时代,数据分析能力备受青睐,数据分析能力频繁出现在岗位需求的描述中,不分岗位的任职要求中,会特意标出“熟 ...
2025-04-03在当今数字化时代,数据分析师的重要性与日俱增。但许多人在踏上这条职业道路时,往往充满疑惑: 如何成为一名数据分析师?成为 ...
2025-04-02最近我发现一个绝招,用DeepSeek AI处理Excel数据简直太爽了!处理速度嘎嘎快! 平常一整天的表格处理工作,现在只要三步就能搞 ...
2025-04-01你是否被统计学复杂的理论和晦涩的公式劝退过?别担心,“山有木兮:统计学极简入门(Python)” 将为你一一化解这些难题。课程 ...
2025-03-31在电商、零售、甚至内容付费业务中,你真的了解你的客户吗? 有些客户下了一两次单就消失了,有些人每个月都回购,有些人曾经是 ...
2025-03-31在数字化浪潮中,数据驱动决策已成为企业发展的核心竞争力,数据分析人才的需求持续飙升。世界经济论坛发布的《未来就业报告》, ...
2025-03-28你有没有遇到过这样的情况?流量进来了,转化率却不高,辛辛苦苦拉来的用户,最后大部分都悄无声息地离开了,这时候漏斗分析就非 ...
2025-03-27