楼主: tree_new_bee

递归with真是个好东西

[复制链接]
论坛徽章:
10
CTO参与奖
日期:2009-02-20 09:44:20ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30迷宫蛋
日期:2012-05-07 10:55:58茶鸡蛋
日期:2012-04-19 16:08:262012新春纪念徽章
日期:2012-01-04 11:54:462011新春纪念徽章
日期:2011-01-04 10:24:02数据库板块每日发贴之星
日期:2010-12-19 01:01:02数据库板块每日发贴之星
日期:2010-12-13 01:01:012009日食纪念
日期:2009-07-22 09:30:00优秀写手
日期:2014-02-08 06:00:12
11#
 楼主| 发表于 2010-12-10 10:55 | 只看该作者
原帖由 newkid 于 2010-12-10 09:17 发表
我把它称为“分解子查询”,自己杜撰的翻译。


好像还比较贴切。

使用道具 举报

回复
论坛徽章:
10
CTO参与奖
日期:2009-02-20 09:44:20ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30迷宫蛋
日期:2012-05-07 10:55:58茶鸡蛋
日期:2012-04-19 16:08:262012新春纪念徽章
日期:2012-01-04 11:54:462011新春纪念徽章
日期:2011-01-04 10:24:02数据库板块每日发贴之星
日期:2010-12-19 01:01:02数据库板块每日发贴之星
日期:2010-12-13 01:01:012009日食纪念
日期:2009-07-22 09:30:00优秀写手
日期:2014-02-08 06:00:12
12#
 楼主| 发表于 2010-12-10 10:58 | 只看该作者
看了看newkid的写法,才知道我先去构造序列表很愚蠢。
这个东西的思维习惯需要逐步适应。


修改后的阶乘:

with targ as (select 30 d from dual)
, prod(lastnum, lastprod) as
(select 1, 1  from dual
union all
select lastnum+1, (lastnum+1)*lastprod
from prod,targ
where lastnum < d
)
select * from prod,targ where lastnum = d

使用道具 举报

回复
论坛徽章:
1088
金色在线徽章
日期:2007-04-25 04:02:08金色在线徽章
日期:2007-06-29 04:02:43金色在线徽章
日期:2007-03-11 04:02:02在线时间
日期:2007-04-11 04:01:02在线时间
日期:2007-04-12 04:01:02在线时间
日期:2007-03-07 04:01:022008版在线时间
日期:2010-05-01 00:01:152008版在线时间
日期:2011-05-01 00:01:342008版在线时间
日期:2008-06-03 11:59:43ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30
13#
发表于 2010-12-10 12:50 | 只看该作者
不错,再写写可以射你一下

使用道具 举报

回复
论坛徽章:
10
CTO参与奖
日期:2009-02-20 09:44:20ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30迷宫蛋
日期:2012-05-07 10:55:58茶鸡蛋
日期:2012-04-19 16:08:262012新春纪念徽章
日期:2012-01-04 11:54:462011新春纪念徽章
日期:2011-01-04 10:24:02数据库板块每日发贴之星
日期:2010-12-19 01:01:02数据库板块每日发贴之星
日期:2010-12-13 01:01:012009日食纪念
日期:2009-07-22 09:30:00优秀写手
日期:2014-02-08 06:00:12
14#
 楼主| 发表于 2010-12-10 13:05 | 只看该作者
原帖由 dingjun123 于 2010-12-10 12:50 发表
不错,再写写可以射你一下

什么叫射一下?

使用道具 举报

回复
论坛徽章:
10
CTO参与奖
日期:2009-02-20 09:44:20ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30迷宫蛋
日期:2012-05-07 10:55:58茶鸡蛋
日期:2012-04-19 16:08:262012新春纪念徽章
日期:2012-01-04 11:54:462011新春纪念徽章
日期:2011-01-04 10:24:02数据库板块每日发贴之星
日期:2010-12-19 01:01:02数据库板块每日发贴之星
日期:2010-12-13 01:01:012009日食纪念
日期:2009-07-22 09:30:00优秀写手
日期:2014-02-08 06:00:12
15#
 楼主| 发表于 2010-12-10 13:09 | 只看该作者
原帖由 newkid 于 2010-12-10 03:23 发表


前阵子我写了个辗转相除法求n个数的最小公倍数,你要不要来试一下?


两个数的好整:

with targ as (select 35 n1, 14 n2 from dual)
, gcd(a, b) as
(select n1 , n2  from targ
union all
select b,
mod(a,b)
from gcd where b>0
)
select * from gcd where b=0


多个数好麻烦,递归里面套递归, 一时想不清楚怎么往一块组装。

使用道具 举报

回复
论坛徽章:
0
16#
发表于 2010-12-10 14:46 | 只看该作者
楼主好样儿的,楼主加油~~

使用道具 举报

回复
论坛徽章:
10
CTO参与奖
日期:2009-02-20 09:44:20ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30迷宫蛋
日期:2012-05-07 10:55:58茶鸡蛋
日期:2012-04-19 16:08:262012新春纪念徽章
日期:2012-01-04 11:54:462011新春纪念徽章
日期:2011-01-04 10:24:02数据库板块每日发贴之星
日期:2010-12-19 01:01:02数据库板块每日发贴之星
日期:2010-12-13 01:01:012009日食纪念
日期:2009-07-22 09:30:00优秀写手
日期:2014-02-08 06:00:12
17#
 楼主| 发表于 2010-12-10 14:49 | 只看该作者
苦战老半天, 终于整出一个n个数的gcd.

with t as (
select 20 n  from dual union all
select 30 from dual union all
select 10 from dual union all
select 45 from dual)
,t1 as (select n n1, lead(n ,1) over (order by n desc) n2 from t )
,t2 as (select max(n1) n1, max(n2)n2  from t1 )
, mgcd(a,b, a2, b2) as
(select n1, n2, n1, n2 from t2
union all
select
case when b2=0 then (select max(n) from t where n<a) else a end,
case when b2=0 then a2 else b end,
case when b2=0 then (select max(n) from t where n<a) else b2 end,
case when b2=0 then  a2 else mod(a2, b2) end
from mgcd where a is not null
)
cycle a,b,a2,b2 set iscycle to 'y' default 'n'
select min(a2) from mgcd where b2=0


SQL> /

   MIN(A2)
----------
         5

Executed in 0.031 seconds

SQL>

使用道具 举报

回复
论坛徽章:
10
CTO参与奖
日期:2009-02-20 09:44:20ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30迷宫蛋
日期:2012-05-07 10:55:58茶鸡蛋
日期:2012-04-19 16:08:262012新春纪念徽章
日期:2012-01-04 11:54:462011新春纪念徽章
日期:2011-01-04 10:24:02数据库板块每日发贴之星
日期:2010-12-19 01:01:02数据库板块每日发贴之星
日期:2010-12-13 01:01:012009日食纪念
日期:2009-07-22 09:30:00优秀写手
日期:2014-02-08 06:00:12
18#
 楼主| 发表于 2010-12-10 21:00 | 只看该作者
有了gcd, 看似计算lcm很容易, 实现起来却是很麻烦。

找了一个比较简单的递归算法来实现多个数的lcm

with t as ( select 20 n1, 30 n2, 10 n3, 45 n4 from dual)
, mlcm (m1, m2, m3, m4)
as ( select n1, n2, n3, n4 from t
union all
select
case when m1 = least(m1,m2,m3,m4) then m1+n1 else m1 end,
case when m2 = least(m1,m2,m3,m4) then m2+n2 else m2 end,
case when m3 = least(m1,m2,m3,m4) then m3+n3 else m3 end,
case when m4 = least(m1,m2,m3,m4) then m4+n4 else m4 end
from mlcm, t where not (m1= m2 and m1=m3 and m1=m4 )
)
select max(m1) from mlcm

SQL> /

   MAX(M1)
----------
       180

Executed in 0.063 seconds



至于辗转相除计算lcm, 实际上还是没做出来。 newkid, 我先欠着, 以后再说。

使用道具 举报

回复
论坛徽章:
10
CTO参与奖
日期:2009-02-20 09:44:20ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30迷宫蛋
日期:2012-05-07 10:55:58茶鸡蛋
日期:2012-04-19 16:08:262012新春纪念徽章
日期:2012-01-04 11:54:462011新春纪念徽章
日期:2011-01-04 10:24:02数据库板块每日发贴之星
日期:2010-12-19 01:01:02数据库板块每日发贴之星
日期:2010-12-13 01:01:012009日食纪念
日期:2009-07-22 09:30:00优秀写手
日期:2014-02-08 06:00:12
19#
 楼主| 发表于 2010-12-10 21:06 | 只看该作者
在顶楼,把做过的问题总结了一下。

使用道具 举报

回复
论坛徽章:
10
CTO参与奖
日期:2009-02-20 09:44:20ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30迷宫蛋
日期:2012-05-07 10:55:58茶鸡蛋
日期:2012-04-19 16:08:262012新春纪念徽章
日期:2012-01-04 11:54:462011新春纪念徽章
日期:2011-01-04 10:24:02数据库板块每日发贴之星
日期:2010-12-19 01:01:02数据库板块每日发贴之星
日期:2010-12-13 01:01:012009日食纪念
日期:2009-07-22 09:30:00优秀写手
日期:2014-02-08 06:00:12
20#
 楼主| 发表于 2010-12-10 21:12 | 只看该作者
菲波纳契数列。
弄过难的,这个就很简单了。

WITH t(r,a,b) AS (
SELECT 1,0,1 FROM DUAL
UNION ALL
SELECT r+1
      ,b
      ,a+b
  FROM t
WHERE r<10
)
cycle a,b set iscycle to 'y' default 'n'
select r,b from t

12  /

         R          B
---------- ----------
         1          1
         2          1
         3          2
         4          3
         5          5
         6          8
         7         13
         8         21
         9         34
        10         55

10 rows selected

Executed in 0.203 seconds

SQL>

如果不是从1,1开始, 而是从1,2开始, cycle语句就能省下了。

使用道具 举报

回复

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

本版积分规则 发表回复

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