当前位置: 首页 > news >正文

Where case when条件改写经验总结

1、问题

项目中遇到where case when的写法,如下:

selectcount(1)from t1 wherecasewhenstype=1and cstatein(1,2)thenetimeelsewtime END BETWEEN TO_DATE(TO_CHAR(?,'YYYY-MM-DD')||'00:00:00','YYYY-MM-DD HH24:MI:SS')AND TO_DATE(TO_CHAR(sysdate,'YYYY-MM-DD')||'23:59:59','YYYY-MM-DD HH24:MI:SS')参数:2026-07-01

计划:

Case when逻辑上是“or”运算,上面语句的意思是
要么 stype=1 and cstate in (1,2) 则选择etime,要么不是stype=1 and cstate in (1,2),则选择wtime,因此是or运算,为了让时间条件能用上索引,我们可以改写成or,另外or又可以转换成union all,整体改写思路拆解如下:
首先
case when stype=1 and cstate in (1,2) then etime
等价于
(stype=1 and cstate in (1,2) and etime
BETWEEN TO_DATE(TO_CHAR(?, ‘YYYY-MM-DD’) || ‘00:00:00’, ‘YYYY-MM-DD HH24:MI:SS’)
AND TO_DATE(TO_CHAR(sysdate, ‘YYYY-MM-DD’) || ‘23:59:59’, ‘YYYY-MM-DD HH24:MI:SS’))
然后
else wtime,排除stype=1 and cstate in (1,2)的数据就要用wtime
那就是
(stype<>1 or cstate not in (1,2))
and wtime BETWEEN TO_DATE(TO_CHAR(?, ‘YYYY-MM-DD’) || ‘00:00:00’, ‘YYYY-MM-DD HH24:MI:SS’)
AND TO_DATE(TO_CHAR(sysdate, ‘YYYY-MM-DD’) || ‘23:59:59’, ‘YYYY-MM-DD HH24:MI:SS’)
)
那么整个语句由以上两部分组成,互相没有交集,最终用union all进行合并。

2、改写

selectcount(1)from(select * from t1 a where(stype=1and cstatein(1,2)and etime BETWEEN TO_DATE(TO_CHAR(?,'YYYY-MM-DD')||'00:00:00','YYYY-MM-DD HH24:MI:SS')AND TO_DATE(TO_CHAR(sysdate,'YYYY-MM-DD')||'23:59:59','YYYY-MM-DD HH24:MI:SS'))union allselect* from t1 where(stype<>1or cstate notin(1,2))and wtime BETWEEN TO_DATE(TO_CHAR(?,'YYYY-MM-DD')||'00:00:00','YYYY-MM-DD HH24:MI:SS')AND TO_DATE(TO_CHAR(sysdate,'YYYY-MM-DD')||'23:59:59','YYYY-MM-DD HH24:MI:SS'))参数:2026-07-012026-07-01

计划:

执行时间:从0.381s下降到0.150s

3、小结

(1)改写用到的逻辑是case when和or、union all之间的相互转换,其中注意的是如果语句能用上索引提升性能,那么就可以将case when转换成or条件。
(2)优化改写考虑是"对症下药",方法很多,重要的是有效。

4、测试数据

create table t1(id varchar(36)primary key,bcode varchar2(4),"ETIME"timestamp,"WTIME"timestamp, STYPE int,CSTATE number(2,0))partition by list(bcode)(partition p_1 values('0301'), partition p_2 values('0302'), partition p_3 values('0303'), partition p_4 values('0304'), partition p_5 values('0305'), partition p_6 values('0306'), partition p_7 values('0307'), partition p_8 values('0308'), partition p_9 values('0309'), partition p_10 values('0310'), partition p_11 values('0311'), partition p_12 values('0312'), partition p_13 values('0313'), partition p_14 values('0314'));insert into t1selectguid(),'0'||to_char(round(dbms_random.value(301,314),0)),sysdate-round(dbms_random.value(1,1000),0),sysdate-round(dbms_random.value(1,1000),0), round(dbms_random.value(1,5),0),round(dbms_random.value(1,5),0)from dual connect by level<=500000;commit;dbms_stats.gather_table_stats(USER,'T1',null,100);create index IDX_DM_T1_ETIME on T1(ETIME)global;create index IDX_DM_T1_WTIME on T1(WTIME)global;selectcount(1)from t1 wherecasewhenstype=1and cstatein(1,2)thenetimeelsewtime END BETWEEN TO_DATE(TO_CHAR('2026-01-01','YYYY-MM-DD')||'00:00:00','YYYY-MM-DD HH24:MI:SS')AND TO_DATE(TO_CHAR(sysdate,'YYYY-MM-DD')||'23:59:59','YYYY-MM-DD HH24:MI:SS')
http://www.jsqmd.com/news/1178827/

相关文章:

  • 终极Magisk Root指南:如何安全解锁Android设备的完整潜能
  • 2026年7月诚信的二手蒸发器厂家推荐,二手钛材反应釜/二手玻璃钢储罐/二手搪玻璃反应釜,二手蒸发器回收企业推荐 - 品牌推荐师
  • L9958与TM4C129XNCZAD的高性能电机控制系统设计
  • Visual Studio 2022 MFC DLL 创建实战:3步生成 .h/.lib/.dll 三件套
  • Java中JDK、JRE、JVM三者之间的关系详解
  • C++桥接模式实战:解决类爆炸与平台依赖的优雅方案
  • 终极AEUX完整指南:如何用3步实现Figma到After Effects的无缝动画转换
  • NLP自然语言处理实战:从文本预处理到深度学习文本分类
  • RAG文档切片(Chunking)核心策略
  • Neo4j Desktop 1.4.9 安装避坑:Windows 10/11 解决 3 类常见启动报错
  • Word 长文档排版实战:3级标题样式与导航窗格高效联动
  • 模板驱动型文档自动化:无代码实现结构化内容动态生成
  • Disruptor-cpp:C++高性能内存队列实现原理与实战应用
  • 前端音频播放组件选型:5款Vue Audio库功能与API深度评测
  • C++单元测试实战:从零掌握Google Test框架与工程实践
  • SolidWorks 2016 URDF插件配置:3步完成阿克曼小车模型导出与ROS验证
  • 2026美国哈佛耶鲁斯坦福录取多的留学机构有哪些?十家高端申请中介完整比较 - 环球新视野
  • STM32L4与L9958电机控制方案设计与优化
  • Tushare接口文档:ST风险警示板股票(st)
  • Qt C++科学计算器开发:从算法到GUI的完整工程实践
  • 8张RTX 4090部署DeepSeek性能测试:Tokens生成速度与优化实践
  • Socket异常连接自动清理方案
  • 【学习笔记】OpenAI 兼容 API 服务化:从协议到 LLM Gateway(19/35)
  • C++大型矩阵运算性能优化:表达式模板与内存管理实战
  • 上下文无关文法 (CFG) 实战:3步构建无二义性四则运算语法树
  • AWS Lambda 入门与生产实践:原理、调优与避坑指南
  • 模板驱动型文档自动化:从填空式生成到智能合规输出
  • 硬盘数据恢复实战:从故障分类到完整解决方案
  • # 360安全卫士极速版:从安装到入门完全指南
  • 【多线程 】线程状态 线程停止 线程休眠 线程礼让 线程插队(Join) 线程状态观测 线程优先级 守护线程 并发 线程同步 队列和锁 线程同步