sql语句的case-end语句的疑似bug经历

原创 2007年10月15日 16:46:00

给客服部做客户分级服务的客户信息设置。要求根据客户历史积分、客户投资成本两个指标对客户进行评级。客户级别分为4级:
    级别1-integral介于[0, 8188]或者investcost介于[ 0, 50000]
    级别2-integral介于[8188, 15888]或者investcost介于[ 50000, 500000]
    级别3-integral介于[15888, 98888]或者investcost介于[ 500000, 100000]
    级别4-integral介于[15888, 无穷大]或者investcost介于[ 100000, 无穷大]

没仔细细想,将两个表联查,并根据integral和investcost两个字段,生成一个levelsign字段。sql代码如下:
CREATE TABLE tcustlevel AS
SELECT t.customerid, --t.customertypesign, t.customerlevelsign, t.customerintegral, nvl(t2.investcost, 0) investcost,
    (case
    when (t.customerintegral >= 0 AND t.customerintegral < 8188) OR (nvl(t2.investcost, 0) >= 0 AND nvl(t2.investcost, 0) < 50000)
        then '1'
    when (t.customerintegral >= 8188 AND t.customerintegral < 15888) OR (nvl(t2.investcost, 0) >= 50000 AND nvl(t2.investcost, 0) < 500000)
        then '2'
    when (t.customerintegral >= 15888 AND t.customerintegral < 98888) OR (nvl(t2.investcost, 0) >= 500000 AND nvl(t2.investcost, 0) < 1000000)
        then '3'
    when (t.customerintegral >= 98888) OR (nvl(t2.investcost, 0) >= 1000000)
        THEN '4'
    end) levelsign--, t.*, t2.*
--SELECT COUNT(*)    
FROM tcustintegral t, tcustcost t2
WHERE 1 = 1
AND t.customerid = t2.customerid(+);
后来实际用到levelsign数据后,才发现,这样写存在一个大bug!!!比如当(integral, investcost) =(15234,792561)时,levelsign应该取3,但结果取值为2。

突然发现以前解决过类似的问题,这是由于case-end的顺序执行和A or B的条件判断两个因素造成的。case-end顺序执行子句中的每一个条件,满足则输出结果并结束后续子句的执行,否则执行下一个子句(即判断条件)。按照上面给定的值,在第2个子句(t.customerintegral >= 8188 AND t.customerintegral < 15888) OR (nvl(t2.investcost, 0) >= 50000 AND nvl(t2.investcost, 0) < 500000)时条件为真,所以输出'2',忽略后续余下子句中的判断条件。

鉴于本问题中的情况,耍了个小伎俩,将执行顺序颠倒,就可以避免错误,输出正确结果,唯一的缺憾是非最优美的解决方案(即万一后来人维护该段代码时,改变了子句顺序,则又会出错了)。所以只好在该段代码头上加上了一段提示性的注释,特别提醒注意。
CREATE TABLE tcustlevel AS
SELECT t.customerid, --t.customertypesign, t.customerlevelsign, t.customerintegral, nvl(t2.investcost, 0) investcost,
    (case
    when (t.customerintegral >= 98888) OR (nvl(t2.investcost, 0) >= 1000000)
        THEN '4'
    when (t.customerintegral >= 15888 AND t.customerintegral < 98888) OR (nvl(t2.investcost, 0) >= 500000 AND nvl(t2.investcost, 0) < 1000000)
        then '3'
    when (t.customerintegral >= 8188 AND t.customerintegral < 15888) OR (nvl(t2.investcost, 0) >= 50000 AND nvl(t2.investcost, 0) < 500000)
        then '2'
    when (t.customerintegral >= 0 AND t.customerintegral < 8188) OR (nvl(t2.investcost, 0) >= 0 AND nvl(t2.investcost, 0) < 50000)
        then '1'
    end) levelsign--, t.*, t2.*
--SELECT COUNT(*)    
FROM tcustintegral t, tcustcost t2
WHERE 1 = 1
AND t.customerid = t2.customerid(+)

纵观本次错误经历,再次验证coding时要想不冒bug真得很难!!!

经典SQL查询语句大全

SQL经典查询语句基础、提升、技巧
  • hundan_520520
  • hundan_520520
  • 2016年12月12日 10:43
  • 1084

SQL语句大全实例

SQL语句实例   表操作     例 1  对于表的教学管理数据库中的表 STUDENTS ,可以定义如下:    CREATE TABLE  STUDENTS   (SNO      N...
  • nanyanglu
  • nanyanglu
  • 2016年11月16日 16:17
  • 4411

SQL基础语句汇总

引言 语法 基础 连接数据库 查看数据库 使用数据库 查看表 查看表结构 建表 修改表 添加字段 移除字段 变更字段 插入 全字段插入 个别字段插入 普通查询 单表全字段查询 单表个别字段查询 多表查...
  • wenwen091100304
  • wenwen091100304
  • 2015年10月24日 11:27
  • 11939

简单 sql 语句 实用大全

一、基础   1、说明:创建数据库   CREATE DATABASE database-name   2、说明:删除数据库   drop database dbname   3、说明:备份...
  • li_yangyang_li
  • li_yangyang_li
  • 2015年12月29日 20:29
  • 1782

SQL语句查询语句完整语法

数据库是mysql,使用的数据库表名称是my_student. 表的完整数据信息是: 完整语法是: Select [select选项] 字段列表[字段别名]/* from 数据源 [...
  • u011991249
  • u011991249
  • 2017年03月21日 21:28
  • 498

Sql server语句(增删改查)

1增 1.1【插入单行】 insert [into]  (列名) values (列值) 例:insert into Strdents (姓名,性别,出生日期) values ('开心朋朋','...
  • Yu_Rong
  • Yu_Rong
  • 2015年10月17日 21:56
  • 8318

sql语句优化的13种方法

原文链接:http://blog.csdn.net/u012942818/article/details/53969972 1,什么是“执行计划”? 执行计划是数据库根据SQL语句和相关表的统计信息...
  • xie_xiansheng
  • xie_xiansheng
  • 2017年05月02日 10:08
  • 544

常用SQL语句总结

总结了一下常用的SQL语句: DDL—数据定义语言(Create,Alter,Drop,DECLARE)  DML—数据操纵语言(Select,Delete,Update,Insert)  DC...
  • sunsfan
  • sunsfan
  • 2016年09月14日 13:51
  • 975

SQL语句基本用法

把SQL的一些常用语句复习了一遍。整理如下:1增1.1【插入单行】 insert [into] (列名) values (列值) 例:insert into Strdents (姓名,性别,出生...
  • Army_Jun
  • Army_Jun
  • 2016年03月11日 10:22
  • 1498

[MySQL学习]常用SQL语句大全总结

转载地址:http://www.cnblogs.com/0351jiazhuang/p/4530366.htmlSQL是(Structured Query Language)结构化查询语言的简称,下面...
  • Hanrovey
  • Hanrovey
  • 2017年03月31日 10:02
  • 6861
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:sql语句的case-end语句的疑似bug经历
举报原因:
原因补充:

(最多只允许输入30个字)