ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 无意之中,一个困惑了N久的问题找到了

无意之中,一个困惑了N久的问题找到了

原创 Linux操作系统 作者:shiguibao 时间:2008-05-05 16:51:20 0 删除 编辑

先看一个语句
我想查一个客户时间段内每个分类的数量和金额,并且按总量统计
SELECT B.CODE_ID,SUM(A.SAL_AMT) SAL_AMT,SUM(A.SAL_MNY) SAL_MNY
FROM SALE_CUST_PROD_MONTH A, (SELECT A.PROD_CODE,A.PROD_NAME,B.CODE_ID,B.CODE_NAME FROM BAS_PROD_INFO A,
(SELECT CODE_ID,CODE_NAME FROM BAS_TYPE_CODE WHERE TYPE_CODE = 'PROD_SORT') B
WHERE A.PROD_SORT = B.CODE_ID) B WHERE A.COMP_CODE = '11640101'
AND OPER_MONTH >= '200801' AND OPER_MONTH <= '200802' AND A.PROD_CODE = B.PROD_CODE
AND A.CUST_CODE = '640101006250'
GROUP BY GROUPING SETS((B.CODE_ID),1);

CODE_ID SAL_AMT SAL_MNY
11   33   9042
15   24   858
13   51   4053
12   18   2193
21   17   328.5
14   46   2089.5
20   6    162
null  195   18726
(null 是为了说明方便加上的,真实的数据为空)

GROUPING SETS 是一个很强大的分组函数,可以实现包括rollup,cube 这些分组函数功能,这里的(B.CODE_ID)表示按 CODE_ID 分组,1 表示显示汇总量。

接下来,我需要根据传入的参数,对数量和金额进行一个转换(比如金额显示成万元,数量显示成箱)
SELECT B.CODE_ID,SUM(A.SAL_AMT)*0.2 SAL_AMT,SUM(A.SAL_MNY)/10000 SAL_MNY
FROM SALE_CUST_PROD_MONTH A, (SELECT A.PROD_CODE,A.PROD_NAME,B.CODE_ID,B.CODE_NAME FROM BAS_PROD_INFO A,
(SELECT CODE_ID,CODE_NAME FROM BAS_TYPE_CODE WHERE TYPE_CODE = 'PROD_SORT') B
WHERE A.PROD_SORT = B.CODE_ID) B WHERE A.COMP_CODE = '11640101'
AND OPER_MONTH >= '200801' AND OPER_MONTH <= '200802' AND A.PROD_CODE = B.PROD_CODE
AND A.CUST_CODE = '640101006250'
GROUP BY GROUPING SETS((B.CODE_ID),1);

CODE_ID SAL_AMT SAL_MNY
11    6.6   0.9042
15    4.8   0.0858
13    10.2  0.4053
12    3.6   0.2193
21    3.4   0.03285
14    9.2   0.20895
20    1.2   0.0162
null   39   1.8726
这样也没错

可是,当语句变成
SELECT B.CODE_ID,SUM(A.SAL_AMT)*1 SAL_AMT,SUM(A.SAL_MNY)/1 SAL_MNY
FROM SALE_CUST_PROD_MONTH A, (SELECT A.PROD_CODE,A.PROD_NAME,B.CODE_ID,B.CODE_NAME FROM BAS_PROD_INFO A,
(SELECT CODE_ID,CODE_NAME FROM BAS_TYPE_CODE WHERE TYPE_CODE = 'PROD_SORT') B
WHERE A.PROD_SORT = B.CODE_ID) B WHERE A.COMP_CODE = '11640101'
AND OPER_MONTH >= '200801' AND OPER_MONTH <= '200802' AND A.PROD_CODE = B.PROD_CODE
AND A.CUST_CODE = '640101006250'
GROUP BY GROUPING SETS((B.CODE_ID),1);
即想显示原来的单位时,问题来了

CODE_ID SAL_AMT SAL_MNY
13   null  null 
21   null  null 
11   null  null 
12   null  null 
20   null  null 
14   null  null 
15   null  null 
null  195   18726

除了合计,数量和金额都变成空值了,将数据计算移到括弧里面,却又正常了

SELECT B.CODE_ID,SUM(A.SAL_AMT*1) SAL_AMT,SUM(A.SAL_MNY/1) SAL_MNY
FROM SALE_CUST_PROD_MONTH A, (SELECT A.PROD_CODE,A.PROD_NAME,B.CODE_ID,B.CODE_NAME FROM BAS_PROD_INFO A,
(SELECT CODE_ID,CODE_NAME FROM BAS_TYPE_CODE WHERE TYPE_CODE = 'PROD_SORT') B
WHERE A.PROD_SORT = B.CODE_ID) B WHERE A.COMP_CODE = '11640101'
AND OPER_MONTH >= '200801' AND OPER_MONTH <= '200802' AND A.PROD_CODE = B.PROD_CODE
AND A.CUST_CODE = '640101006250'
GROUP BY GROUPING SETS((B.CODE_ID),1);

CODE_ID SAL_AMT SAL_MNY
11   33   9042
15   24   858
13   51   4053
12   18   2193
21   17   328.5
14   46   2089.5
20   6    162
null  195   18726

因为是突然发生的,根本找不到原因,只好改语句,可是后来又有类似的语句发生此类问题,一直无解,只能改语句了事。
今天,突然意识到,会不会就是这个GROUPING SETS 的问题,因为 1 表示汇总,用() 也是一样的效果(官方是推荐用()的)
于是把语句改成
SELECT B.CODE_ID,SUM(A.SAL_AMT)*1 SAL_AMT,SUM(A.SAL_MNY)/1 SAL_MNY
FROM SALE_CUST_PROD_MONTH A, (SELECT A.PROD_CODE,A.PROD_NAME,B.CODE_ID,B.CODE_NAME FROM BAS_PROD_INFO A,
(SELECT CODE_ID,CODE_NAME FROM BAS_TYPE_CODE WHERE TYPE_CODE = 'PROD_SORT') B
WHERE A.PROD_SORT = B.CODE_ID) B WHERE A.COMP_CODE = '11640101'
AND OPER_MONTH >= '200801' AND OPER_MONTH <= '200802' AND A.PROD_CODE = B.PROD_CODE
AND A.CUST_CODE = '640101006250'
GROUP BY GROUPING SETS((B.CODE_ID),());

一切变的安静了,数据正常的显示。
找到了问题的根源,可是,究竟为什么这样呢,还没有确切的解释,不知道是不是oracle的一个bug了。
记下来,也许以后有答案呢。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/177967/viewspace-260417/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: 生死不离--转载
请登录后发表评论 登录
全部评论

注册时间:2008-05-01

  • 博文量
    18
  • 访问量
    22861