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真得很难!!!

case when end用法

oracle中case when end 用法,直接上图,yim
  • u011897392
  • u011897392
  • 2014-08-29 16:09:11
  • 1847

sql case end

create database demo use demo create table [user] ( [uId] int identity(1,1) primary key, [n...
  • chaojishuaigeli
  • chaojishuaigeli
  • 2012-11-09 12:02:51
  • 1669

SQL中 case when then end的用法

示例一SELECT 学号, 姓名,  等级=     CASE     WHEN 总学分 IS NULL THEN ‘尚未选课’       WHEN 总学分         WHEN 总学分 >=5...
  • add8849
  • add8849
  • 2006-01-11 16:22:00
  • 28889

Oracle Case end用法

1.黑马程序员之SQL学习笔记:表中有ABC三列,用SQL语句实现,当A列大于B列时选择A列否则选择B列,当B列大于C列时选择B列否则选择C列。 select (case when a>b then ...
  • ItJavawfc
  • ItJavawfc
  • 2014-07-15 08:53:55
  • 1482

[ORACLE] case when then else end 应用

Case when 的用法,简单Case函数 简单CASE表达式,使用表达式确定返回值.   语法:   CASE search_expression   WHEN expression1 ...
  • wangshfa
  • wangshfa
  • 2014-03-17 10:54:16
  • 86711

SQL数据库中Case End语句应用总结

Select  PR_PT.cTmpCode,max(PR_PT.cTmpName) as cTmpName,max(PR_PT.cDescription) as cDescription,case ...
  • dangdangxl
  • dangdangxl
  • 2012-06-29 08:52:43
  • 151

sql语句

  • 2011年05月11日 14:02
  • 2KB
  • 下载

SQL 经典语句

  • 2011年09月28日 16:35
  • 48KB
  • 下载

SQL中case,when,then,end的用法(…

转载自:http://blog.csdn.net/chaojishuaigeli/article/details/8165802 create database demo   use d...
  • qq_20630893
  • qq_20630893
  • 2017-08-04 15:51:29
  • 161

ms sql server 语法 CASE WHEN THEN END 的使用

CASE (Transact-SQL) Other Versions   THIS TOPIC APPLIES TO: SQL Server (starting with 200...
  • joyous
  • joyous
  • 2016-08-15 05:37:03
  • 1407
收藏助手
不良信息举报
您举报文章:sql语句的case-end语句的疑似bug经历
举报原因:
原因补充:

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