查看: 40702|回复: 106

实现四则运算的一条sql语句

[复制链接]
论坛徽章:
21
红旗
日期:2013-09-30 15:26:01凯迪拉克
日期:2013-10-23 12:48:26比亚迪
日期:2013-11-01 09:19:01奔驰
日期:2013-12-13 09:27:30马上有对象
日期:2014-11-18 10:46:242015年新春福章
日期:2015-04-28 15:24:55慢羊羊
日期:2015-05-28 09:49:31
跳转到指定楼层
1#
发表于 2008-9-5 16:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1.建立一个测试表
create table mar_test( id number, text varchar2(200))
      
      insert into mar_Test values ( 1,'12+556-543*152/2423+23*2*435+34-234');
      insert into mar_Test values ( 2,'12/2/3/4');
      insert into mar_Test values ( 3,'1*2*34');
      insert into mar_Test values ( 4,'1+5-5*2/5+3*2*4*5+34-2');

   select a.id,max(text) text,
          sum(regexp_substr(add_text,'[0-9]+',1,n)*decode(regexp_substr('+'||add_text,'[^0-9]',1,n),'+',1,-1))   --加减部分 计算之和
          +
          nvl(sum( (select  decode(substr(regexp_substr('+'||text,'[+|-]([0-9]+[*|/]+)+[0-9]+',1,n),1,1),'+',1,-1)
                                   *power(10,Sum(Log(10, decode( regexp_substr('*'||regexp_substr(text,'([0-9]+[*|/]+)+[0-9]+',1,n),'[^0-9]',1,rownum),
                                                                                        '*',  regexp_substr(regexp_substr(text,'([0-9]+[*|/]+)+[0-9]+',1,n),'[0-9]+',1,rownum) ,
                                                                                              1/regexp_substr(regexp_substr(text,'([0-9]+[*|/]+)+[0-9]+',1,n),'[0-9]+',1,rownum)
                                               )  )  )  )
                          from dual
                          connect by rownum <=len )) ,0)  wanted    --乘除部分 计算之和
    from  
                 (select a.id,a.text,
                            length(regexp_replace(text,'[0-9]+'))+1 len,
                            regexp_replace(text,'([0-9]+[*|/]+)+[0-9]+',0) add_text
                   from mar_test a  )     a,
                (select rownum n from dual connect by rownum<100) b
  where a.len>=b.n
  group by id

sql 实现对 text中算式的计算 ,限制就是不能加括号
运算结果
ID        TEXT                                                                        WANTED
1        12+556-543*152/2423+23*2*435+34-234        20343.93644
2        12/2/3/4                                                                        0.5
4        1+5-5*2/5+3*2*4*5+34-2                                        156
3        1*2*34                                                                        68

以前如果算式只有加减没有乘除,结果为null,是以前考虑不周, 现在对乘除部分计算之和加上nvl判断

[ 本帖最后由 grubbyoo 于 2008-10-7 12:05 编辑 ]
论坛徽章:
281
2015年新春福章
日期:2015-03-06 11:57:312012新春纪念徽章
日期:2012-02-13 15:12:252012新春纪念徽章
日期:2012-01-04 11:51:22蛋疼蛋
日期:2011-12-29 07:37:22迷宫蛋
日期:2011-12-26 14:19:41茶鸡蛋
日期:2011-11-17 09:20:52茶鸡蛋
日期:2011-11-10 22:42:38ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15茶鸡蛋
日期:2011-10-24 09:48:48ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47
2#
发表于 2008-9-5 16:22 | 只看该作者

使用道具 举报

回复
论坛徽章:
47
马上加薪
日期:2014-02-19 11:55:142011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:152011新春纪念徽章
日期:2011-01-25 15:41:502011新春纪念徽章
日期:2011-01-25 15:41:012010新春纪念徽章
日期:2010-03-01 11:20:512010年世界杯参赛球队:日本
日期:2010-02-26 11:04:222010新春纪念徽章
日期:2010-01-04 08:33:08祖国60周年纪念徽章
日期:2009-10-09 08:28:00生肖徽章2007版:牛
日期:2009-09-10 11:14:59
3#
发表于 2008-9-5 16:31 | 只看该作者
我想给你加精华可惜没有权限,那就来一只好评

使用道具 举报

回复
论坛徽章:
2
懒羊羊
日期:2015-03-04 14:52:112015年新春福章
日期:2015-03-06 11:58:18
4#
发表于 2008-9-5 16:33 | 只看该作者
顶下,楼主好强!!

使用道具 举报

回复
论坛徽章:
2
懒羊羊
日期:2015-03-04 14:52:112015年新春福章
日期:2015-03-06 11:58:18
5#
发表于 2008-9-5 16:37 | 只看该作者
顶下,楼主好强!!

使用道具 举报

回复
论坛徽章:
21
红旗
日期:2013-09-30 15:26:01凯迪拉克
日期:2013-10-23 12:48:26比亚迪
日期:2013-11-01 09:19:01奔驰
日期:2013-12-13 09:27:30马上有对象
日期:2014-11-18 10:46:242015年新春福章
日期:2015-04-28 15:24:55慢羊羊
日期:2015-05-28 09:49:31
6#
 楼主| 发表于 2008-9-5 16:39 | 只看该作者
原帖由 hotiice 于 2008-9-5 16:31 发表
我想给你加精华可惜没有权限,那就来一只好评

so感谢版主,其实都是看了你的帖子,才搞这么一个 繁复的sql

使用道具 举报

回复
论坛徽章:
40
授权会员
日期:2009-03-04 17:06:25最佳人气徽章
日期:2013-03-19 17:24:25SQL极客
日期:2013-12-09 14:13:35优秀写手
日期:2013-12-18 09:29:09ITPUB元老
日期:2015-03-04 13:33:34白羊座
日期:2016-03-11 13:49:34乌索普
日期:2017-11-17 11:40:00
7#
发表于 2008-9-5 16:49 | 只看该作者
楼主太牛了   佩服  佩服  
下来研究研究

发现楼主很喜欢用 正则式

使用道具 举报

回复
论坛徽章:
69
生肖徽章2007版:羊
日期:2008-11-14 14:42:19复活蛋
日期:2011-08-06 08:59:05ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20版主4段
日期:2012-05-15 15:24:11
8#
发表于 2008-9-5 17:01 | 只看该作者
顶一下, 给朵花

使用道具 举报

回复
论坛徽章:
4
ITPUB元老
日期:2006-06-01 09:52:25ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44生肖徽章2007版:鼠
日期:2008-01-02 17:35:53
9#
发表于 2008-9-5 17:08 | 只看该作者
强,使用上了正则表达式!

使用道具 举报

回复
论坛徽章:
21
红旗
日期:2013-09-30 15:26:01凯迪拉克
日期:2013-10-23 12:48:26比亚迪
日期:2013-11-01 09:19:01奔驰
日期:2013-12-13 09:27:30马上有对象
日期:2014-11-18 10:46:242015年新春福章
日期:2015-04-28 15:24:55慢羊羊
日期:2015-05-28 09:49:31
10#
 楼主| 发表于 2008-9-5 17:23 | 只看该作者
感谢各位版主和坛友的鼓励,格式了一下代码

算法就是
将       '12+556-543*152/2423+23*2*435+34-234'
变成2部分  '12+556-                       0+              0+34-234'
        和  -543*152/2423 ;23*2*435
分别计算求和


select a.id,
       max(text) text,
       sum(regexp_substr(add_text, '[0-9]+', 1, n) *
           decode(regexp_substr('+' || add_text, '[^0-9]', 1, n),
                  '+',
                  1,
                  -1)) +                                                                            --加法的数字求和,乘法和除法分开计算 ,取每个子串前的运算符号,如果为 ‘-’就 乘以-1
       sum((select decode(substr(regexp_substr('+' || text,            
                                              '[+|-]([0-9]+[*|/]+)+[0-9]+',
                                              1,
                                              n),
                                1,
                                1),
                         '+',
                         1,
                         -1) *                                                                   -- 如 25*515/544  子串前的运算符号,如果为 ‘-’就 乘以-1
                  power(10,                                                                  -- 从itpub上学到的 利用lg将 连乘 改为加法
                        Sum(Log(10,
                                decode(regexp_substr('*' ||
                                                     regexp_substr(text,
                                                                   '([0-9]+[*|/]+)+[0-9]+',
                                                                   1,
                                                                   n),
                                                     '[^0-9]',
                                                     1,
                                                     rownum),
                                       '*',
                                       regexp_substr(regexp_substr(text,                       
                                                                   '([0-9]+[*|/]+)+[0-9]+',
                                                                   1,
                                                                   n),
                                                     '[0-9]+',
                                                     1,
                                                     rownum),
                                       1 / regexp_substr(regexp_substr(text,
                                                                       '([0-9]+[*|/]+)+[0-9]+',
                                                                       1,
                                                                       n),
                                                         '[0-9]+',
                                                         1,
                                                         rownum)))))
             from dual
           connect by rownum <= len)) wanted
  from (select a.id,
               a.text,
               length(regexp_replace(text, '[0-9]+')) + 1 len,                         --算式中的数字个数
               regexp_replace(text, '([0-9]+[*|/]+)+[0-9]+', 0) add_text        --将算式中 乘的子式 代替成0, 后面分开计算
          from mar_test a) a,
       (select rownum n from dual connect by rownum < 100) b                 --默认算式最多数字100个
where a.len >= b.n
group by id

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表