楼主: nyfor

[精华] 那个有条件的随机取电影问题用一句SQL实现

[复制链接]
论坛徽章:
23
生肖徽章2007版:蛇
日期:2008-01-02 17:35:53生肖徽章2007版:狗
日期:2009-03-10 21:17:06生肖徽章2007版:虎
日期:2009-03-10 21:20:05生肖徽章2007版:龙
日期:2009-03-10 21:27:46生肖徽章2007版:蛇
日期:2009-03-10 21:34:302009日食纪念
日期:2009-07-22 09:30:00ITPUB8周年纪念徽章
日期:2009-09-27 10:21:21祖国60周年纪念徽章
日期:2009-10-09 08:28:002010新春纪念徽章
日期:2010-01-04 08:33:082010新春纪念徽章
日期:2010-03-01 11:21:01
31#
发表于 2008-7-4 09:11 | 只看该作者
这个题目已经赚了两个精华了!!

使用道具 举报

回复
论坛徽章:
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
32#
 楼主| 发表于 2008-7-4 09:16 | 只看该作者
to: 三思兄, 用
SQL> with tt as(
  2  select filmname ofm,
  3         rtrim(filmname, 'abi') nfm,
  4         count(rtrim(filmname, 'abi')) over(partition by rtrim(filmname, 'abi')) ct,
  5         row_number() over(partition by rtrim(filmname, 'abi') order by 1) rn
  6    from t_film t
  7  )
  8  select ofm from(
  9  select ofm from tt where nfm in(
10  select nfm from(
11  select a.*, sum(ct) over(order by rownum) sv
12    from (select * from tt where rn = 1 order by dbms_random.value) a
13           ) where sv <= 10
14  ) order by ct desc) where rownum<=8
15  /

我连续的执行, 执行到极端情况时,出现错误的结果:
SQL> /

OFM
--------------------------------------------------
侏罗纪公园i
侏罗纪公园ii
侏罗纪公园iii
东方海盗传奇a
东方海盗传奇b
天行者b
太极a
太极b

8 rows selected

使用道具 举报

回复
论坛徽章:
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
33#
 楼主| 发表于 2008-7-4 09:21 | 只看该作者
此外我的代码部分对于极端情况会出现没有结果返回的情况.
这就是主题中说明的: 电影记录够多, 这通常是符合这个条件的.

但是很奇怪, 为什么 比我高一些版本的Oracle 10G下运行却没结果呢.
三思兄的能够在低版中运行, 极端情况下也有问题.

使用道具 举报

回复
论坛徽章:
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
34#
发表于 2008-7-4 09:21 | 只看该作者
原帖由 nyfor 于 2008-7-4 09:16 发表
to: 三思兄, 用
SQL> with tt as(
  2  select filmname ofm,
  3         rtrim(filmname, 'abi') nfm,
  4         count(rtrim(filmname, 'abi')) over(partition by rtrim(filmname, 'abi')) ct,
  5         row_number() over(partition by rtrim(filmname, 'abi') order by 1) rn
  6    from t_film t
  7  )
  8  select ofm from(
  9  select ofm from tt where nfm in(
10  select nfm from(
11  select a.*, sum(ct) over(order by rownum) sv
12    from (select * from tt where rn = 1 order by dbms_random.value) a
13           ) where sv  

再去改进一下算法

使用道具 举报

回复
论坛徽章:
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
35#
发表于 2008-7-4 09:23 | 只看该作者
原帖由 nyfor 于 2008-7-4 09:16 发表
to: 三思兄, 用
SQL> with tt as(
  2  select filmname ofm,
  3         rtrim(filmname, 'abi') nfm,
  4         count(rtrim(filmname, 'abi')) over(partition by rtrim(filmname, 'abi')) ct,
  5         row_number() over(partition by rtrim(filmname, 'abi') order by 1) rn
  6    from t_film t
  7  )
  8  select ofm from(
  9  select ofm from tt where nfm in(
10  select nfm from(
11  select a.*, sum(ct) over(order by rownum) sv
12    from (select * from tt where rn = 1 order by dbms_random.value) a
13           ) where sv  


如果电影库中电影多数都是大于1部的,则极容易出现这种问题~~

这种情况下,我的写法肯定是无能为力了~~

[ 本帖最后由 junsansi 于 2008-7-4 09:24 编辑 ]

使用道具 举报

回复
论坛徽章:
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
36#
 楼主| 发表于 2008-7-4 09:37 | 只看该作者
这样的SQL主要就是训练自己的思维能力, 但没有太大的实用性.
为了避免一些极端情况的出现, 还是要使用存储过程来做, 存储过程可以无限循环直到找到满足条件的记录.
而SQL则无此能力, 无法在不满足条件的情况下重复运行.

使用道具 举报

回复
论坛徽章:
4
奥运会纪念徽章:柔道
日期:2008-07-04 17:49:032009新春纪念徽章
日期:2009-01-04 14:52:282010新春纪念徽章
日期:2010-03-01 11:08:27
37#
发表于 2008-7-4 09:43 | 只看该作者
嗯,学习了

使用道具 举报

回复
论坛徽章:
18
生肖徽章2007版:虎
日期:2008-04-11 18:37:24奥运会纪念徽章:击剑
日期:2008-07-03 11:38:17迷宫蛋
日期:2011-05-10 13:03:40茶鸡蛋
日期:2011-05-10 13:05:16蜘蛛蛋
日期:2011-05-10 13:07:01灰彻蛋
日期:2012-12-10 11:47:16鲜花蛋
日期:2013-07-07 10:07:20
38#
发表于 2008-7-4 09:49 | 只看该作者
原帖由 nyfor 于 2008-7-4 09:37 发表
这样的SQL主要就是训练自己的思维能力, 但没有太大的实用性.
为了避免一些极端情况的出现, 还是要使用存储过程来做, 存储过程可以无限循环直到找到满足条件的记录.
而SQL则无此能力, 无法在不满足条件的情况下重复运行.




我是进来顶这句的

使用道具 举报

回复
论坛徽章:
85
2008新春纪念徽章
日期:2008-02-13 12:43:03双黄蛋
日期:2011-06-17 11:07:502011新春纪念徽章
日期:2011-02-18 11:42:472011新春纪念徽章
日期:2011-01-04 10:24:022010年世界杯参赛球队:荷兰
日期:2010-08-28 00:09:112010年世界杯参赛球队:科特迪瓦
日期:2010-03-02 12:36:542010新春纪念徽章
日期:2010-03-01 11:07:242010新春纪念徽章
日期:2010-03-01 11:07:242010新春纪念徽章
日期:2010-01-04 08:33:082010年世界杯参赛球队:意大利
日期:2009-12-31 14:41:24
39#
发表于 2008-7-4 10:16 | 只看该作者
原帖由 junsansi 于 2008-7-4 09:02 发表

[php]
SQL> with tt as(
  2  select filmname ofm,
  3         rtrim(filmname, 'abi') nfm,
  4         count(rtrim(filmname, 'abi')) over(partition by rtrim(filmname, 'abi')) ct,
  5         row_number() over(partition by rtrim(filmname, 'abi') order by 1) rn
  6    from t_film t
  7  )
  8  select ofm from(
  9  select ofm from tt where nfm in(
10  select nfm from(
11  select a.*, sum(ct) over(order by rownum) sv
12    from (select * from tt where rn = 1 order by dbms_random.value) a
13           ) where sv  /

OFM
--------------------------------------------------
侏罗纪公园i
侏罗纪公园iii
侏罗纪公园ii
天行者b
忍者兵b
忍者兵a
天行者a
爱情呼叫转移

8 rows selected

[/php]

有没有想过,如果第一部是侏罗纪,后面跟的4部都是上下集,还是有可能出现有一部电影不全的情况啊。

使用道具 举报

回复
论坛徽章:
85
2008新春纪念徽章
日期:2008-02-13 12:43:03双黄蛋
日期:2011-06-17 11:07:502011新春纪念徽章
日期:2011-02-18 11:42:472011新春纪念徽章
日期:2011-01-04 10:24:022010年世界杯参赛球队:荷兰
日期:2010-08-28 00:09:112010年世界杯参赛球队:科特迪瓦
日期:2010-03-02 12:36:542010新春纪念徽章
日期:2010-03-01 11:07:242010新春纪念徽章
日期:2010-03-01 11:07:242010新春纪念徽章
日期:2010-01-04 08:33:082010年世界杯参赛球队:意大利
日期:2009-12-31 14:41:24
40#
发表于 2008-7-4 10:17 | 只看该作者
原帖由 nyfor 于 2008-7-4 09:16 发表
to: 三思兄, 用
SQL> with tt as(
  2  select filmname ofm,
  3         rtrim(filmname, 'abi') nfm,
  4         count(rtrim(filmname, 'abi')) over(partition by rtrim(filmname, 'abi')) ct,
  5         row_number() over(partition by rtrim(filmname, 'abi') order by 1) rn
  6    from t_film t
  7  )
  8  select ofm from(
  9  select ofm from tt where nfm in(
10  select nfm from(
11  select a.*, sum(ct) over(order by rownum) sv
12    from (select * from tt where rn = 1 order by dbms_random.value) a
13           ) where sv  

没错,我上个贴说的就是这种情况,其实这道题最难的就在这个地方

使用道具 举报

回复

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

本版积分规则 发表回复

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