一哥们出条sql题给我玩,将下面sql改成不使用keep分析函数的写法。

select deptno,
ename,
sal,
hiredate,
min(sal) keep(dense_rank first order by hiredate) over(partition by deptno) min_sal,
max(sal) keep(dense_rank last order by hiredate) over(partition by deptno) max_sal
from emp;

我一开始改错了,被这哥们喷菜鸡,我草。

-- 错误等价改写,逻辑不等价
with x as (
select e1.deptno,
e1.ename,
e1.sal,
e1.hiredate,
row_number() over (partition by DEPTNO order by HIREDATE) rn_first,
row_number() over (partition by DEPTNO order by HIREDATE DESC) rn_last
from EMP e1)
select
e.deptno,
e.ename,
e.sal,
e.hiredate,
x1.SAL,
x2.SAL
from emp e
inner join x x1 on e.DEPTNO = x1.DEPTNO and x1.rn_first = 1
inner join x x2 on e.DEPTNO = x2.DEPTNO and x2.rn_last = 1;

我换了张表测试下,发现上面改写是逻辑有问题,如果同一个组内有相同日期的分组字段内有NULL值的,确实会导致SQL结果集不一致。

-- 将EMP表替换成EMPLOYEES,如果使用上面等价改写就错误了。
select DEPARTMENT_ID,
FIRST_NAME,
SALARY,
HIRE_DATE,
min(SALARY) keep(dense_rank first order by HIRE_DATE) over(partition by DEPARTMENT_ID) min_sal,
max(SALARY) keep(dense_rank last order by HIRE_DATE) over(partition by DEPARTMENT_ID) max_sal
from EMPLOYEES;

最终等价改写的SQL,增加了分组字段内有NULL值的逻辑和处理一个组内有相同日期的逻辑。

select e.DEPARTMENT_ID,
e.FIRST_NAME,
e.SALARY,
e.HIRE_DATE,
(select MIN_SALARY
from (select DEPARTMENT_ID, MIN(SALARY) MIN_SALARY
from (select DEPARTMENT_ID,
SALARY,
HIRE_DATE,
dense_rank() over (PARTITION BY DEPARTMENT_ID ORDER BY HIRE_DATE) RN
from EMPLOYEES)
WHERE RN = 1
GROUP BY DEPARTMENT_ID) e1
where case when e1.DEPARTMENT_ID is null then 99999 else e1.DEPARTMENT_ID end = case when e.DEPARTMENT_ID is null then 99999 else e.DEPARTMENT_ID end) a_min,
(select MAX_SALARY
from (select DEPARTMENT_ID, MAX(SALARY) MAX_SALARY
from (select DEPARTMENT_ID,
SALARY,
HIRE_DATE,
dense_rank() over (PARTITION BY DEPARTMENT_ID ORDER BY HIRE_DATE DESC) RN
from EMPLOYEES)
WHERE RN = 1
GROUP BY DEPARTMENT_ID) e1
where case when e1.DEPARTMENT_ID is null then 99999 else e1.DEPARTMENT_ID end = case when e.DEPARTMENT_ID is null then 99999 else e.DEPARTMENT_ID end ) a_max
FROM EMPLOYEES e;

差集比较后是等价的:

SQL KEEP 窗口函数等价改写案例的更多相关文章

  1. 小米正式开源 SQL 智能优化与改写工具 SOAR

    近日,小米正式宣布开源 SOAR. 截至今日,该项目已经获得了 350 个「star」以及 44 个「fork」(GitHub项目地址:https://github.com/XiaoMi/soar) ...

  2. Hive Sql的窗口函数

    date: 2019-08-30 11:02:37 updated: 2019-08-30 14:40:00 Hive Sql的窗口函数 1. count.sum.avg.max.min 以 sum ...

  3. SOAR SQL进行优化和改写的自动化工具

    前言 SQL优化是程序开发中经常遇到的问题,尤其是在程序规模不断扩大的时候.SQL的好坏不仅制约着程序的规模,影响着用户的体验,甚至威胁着信息的安全. 我们经常听到说哪家平台挂了,哪家网站被黑了,但我 ...

  4. 总结SQL Server窗口函数的简单使用

    总结SQL Server窗口函数的简单使用 前言:我一直十分喜欢使用SQL Server2005/2008的窗口函数,排名函数ROW_NUMBER()尤甚.今天晚上我在查看SQL Server开发的相 ...

  5. (4.34)sql server窗口函数

    关键词:sql server窗口函数,窗口函数,分析函数 如果分析函数不可用,那么可能是版本还不支持 Window Function 包含了 4 个大类.分别是: 1 - Rank Function ...

  6. SQL Server标量函数改写内联表值函数优化案例

    问题SQL: SELECT TOP 1001 ha.HuntApplicationID , ha.PartyNumber , mht.Name AS MasterHuntTypeName , htly ...

  7. SQL Server 2012安装错误案例:Error while enabling Windows feature: NetFx3, Error Code: -2146498298

    案例环境: 服务器环境 :    Windows Server 2012 R2 Standard 数据库版本 :    SQL Server 2012 SP1 案例介绍:   在Windows Ser ...

  8. 虚拟机备份克隆导致SQL SERVER 出现IO错误案例

      案例环境:   服务器配置: CPU: Intel E5-2690  RAM: 12G   虚拟机 操作系统  : Windows Server 2008 R2 Standard Edtion   ...

  9. SQL Server一致性错误修复案例总结

    今天遇到了一个关于数据库一致性错误的案例.海外工厂的一台SQL Server 2005(9.00.5069.00 Standard Edition)数据库在做DBCC CHECKDB的时候出现了一致性 ...

  10. SQL Server 窗口函数详解:OVER()

    语法 开窗函数支持分区.排序和框架三种元素,其语法格式如下: OVER ( [ <PARTITION BY clause> ] [ <ORDER BY clause> ] [ ...

随机推荐

  1. Android 开发入门(3)

    0x05 活动 Activity (1)启停活动页面 a. 启动和结束 从当前页面跳转至新页面 startActivity(new Intent(this, [targetPage].class)) ...

  2. electron 关于jquery不可以用

    前言 electron 实际是在google 内核上开发,实际上和我们在浏览器还是有些区别的. jquery 在electron 上引用是会出错的. 正文 解决方案 如果不做任何操作,在Electro ...

  3. 深入探讨下SSR与CSR有啥不同

    随着互联网技术的迅速发展,用户对网页的加载速度和交互体验有了更高的期待.作为开发者,我们常常需要在服务器端渲染(SSR)与客户端渲染(CSR)之间做出选择.这两种渲染方式各有特点,适用于不同的场景和需 ...

  4. 在RockyLinux 9.3环境中采用RPM模式部署Oracle 19C

    在RockyLinux 9.3环境中采用RPM模式部署Oracle 19C 用途 在开发数据库系统时,可以验证功能是否与Oracle的表现一致,验证正确性和兼容性 限制 虚拟机安装,CPU 2*4 内 ...

  5. 力扣1127(MySQL)-用户购买平台(困难)

    题目: 支出表: Spending 这张表记录了用户在一个在线购物网站的支出历史,该在线购物平台同时拥有桌面端('desktop')和手机端('mobile')的应用程序.这张表的主键是 (user_ ...

  6. 力扣219(java&python)-存在重复元素 II(简单)

    题目: 给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 i 和 j ,满足 nums[i] == nums[j] 且 abs(i - j) <= k .如果存在 ...

  7. 力扣227(java)-基本计算器Ⅱ(中等)

    题目: 给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值. 整数除法仅保留整数部分. 你可以假设给定的表达式总是有效的.所有中间结果将在 [-231, 231 - 1] 的范围内. ...

  8. 微信不再提供小程序打开App?借助H5为App引流的方式你必须知道!

    简介: 2021年5月14日App开发者领域发布了一条重要消息:微信开放平台为了提升用户体验,将于2021年5月20日(后来延期到2021年5月27日)起不再提供"小程序打开App技术服务& ...

  9. 解密万亿参数M6模型预训练背后的分布式框架Whale

    ​简介: 最近,阿里云PAI团队和达摩院智能计算实验室一起发布"低碳版"巨模型M6,大幅降低万亿参数超大模型训练能耗.借助我们自研的Whale框架仅使用480卡GPU,即训练出了规 ...

  10. [Go] golang 去除 URI 链接中的 query string 参数

    思路是使用 golang 的 net/url 包提供的方法解析url各部分,其中 URL.RawQuery 为查询参数部分,格式如 :a=b&c=d 然后我们再通过 strings.Repla ...