li
  当前位置:主页 > 性能优化 > 文章内容
li
用SQL解决两道有趣的题(二)
来源: http://yangtingkun.itpub.net/  作者: yangtingkun    时间:2008-01-26   阅读:3  

OracleSQL语句功能还是很强的,看到两道比较有趣的题,用SQL来尝试求解。

SQL解决两道有趣的题(一):http://yangtingkun.itpub.net/post/468/448940


第二个问题:

GaussPoincare在天堂相遇了,上帝说:你们都是人间最伟大的数学家,那我来出道题考考你们谁更聪明。我在左手写一个大于1小于100的数,在右手同样写一个大于1小于100的数,然后把他们的和写在Gauss手上,把积写在Poincare手上,看看你们能不能猜出这两个数字是几。
Gauss
看了手上的数字,说:我不知道这两个数字是几,可我保证Poincare也不知道。
Poincare
看了手上的数字,说:我原来的确不知道那两个数字是几,可我现在知道了。

Gauss
说:那我也知道了。
问题:那两个数字是几?

粗看上去似乎和刚才第一题很像,如果仔细研究就会发现二者的区别还是很大的,相比之下,这道题比第一题要难一些。

仍然是先给出SQL解,然后描述一下思路:

SQL> WITH T_NUM AS
2 (SELECT ROWNUM 1 NUM FROM DUAL CONNECT BY LEVEL < 99)
3 SELECT A, B
4 FROM
5 (
6 SELECT
7 A,
8 B,
9 TOTAL,
10 MUL,
11 MUL_P,
12 COUNT(DECODE(MUL_P, 1, 1)) OVER(PARTITION BY TOTAL) VALUE
13 FROM
14 (
15 SELECT
16 A,
17 B,
18 TOTAL,
19 MUL,
20 COUNT(*) OVER (PARTITION BY TOTAL) TOTAL_P,
21 COUNT(*) OVER (PARTITION BY MUL) MUL_P
22 FROM
23 (
24 SELECT
25 A,
26 B,
27 TOTAL,
28 MUL,
29 MIN(MUL_P) OVER (PARTITION BY TOTAL) MUL_M
30 FROM
31 (
32 SELECT
33 A.NUM A,
34 B.NUM B,
35 A.NUM B.NUM TOTAL,
36 A.NUM * B.NUM MUL,
37 COUNT(*) OVER (PARTITION BY A.NUM B.NUM) TOTAL_P,
38 COUNT(*) OVER (PARTITION BY A.NUM * B.NUM) MUL_P
39 FROM T_NUM A, T_NUM B
40 WHERE A.NUM < B.NUM
41 )
42 )
43 WHERE MUL_M != 1
44 )
45 )
46 WHERE MUL_P = 1
47 AND VALUE = 1;

A B
---------- ----------
4 13

下面简单描述一下思路:

WITH语句就是构造一张基础数据表。

最内层的循环构造两个数的笛卡儿积,列出所有的可能,不过对于我们来说,A1B2A2B1没有区别,因此加上限制条件A > B。循环中的分析函数用来计算AB两个数的和相同的个数以及AB两个数的积相同的个数。

IXDBA.NET技术社区

下面到了这道题和第一题的区别之处。Gauss不但自己不知道,还可以确认Poincare也不知道。这说明AB两个数构成Gauss手里的和TATOL不但不是唯一的,而且所有能构成这个TOTALAB的积MUL都不是唯一的。这就是第二层嵌套的含义。

到了第三层,过滤掉上面那些不符合条件的AB之后。要解决的问题就是Poincare知道AB的答案后,Gauss也知道了。

这说明对于TOTAL这个值,所有AB的组合中有一个且只有一个组合它们的乘积是唯一确定的。这是通过第四层嵌套中那个COUNT(DECODE) OVER实现的。

最后过滤乘积唯一,且对于相同TOTAL的所有AB组合中有且仅有一个乘积唯一确定的AB组合。

如果还是不明白,可以将这个嵌套一层层执行,观察每一步的执行结果,有助于理解每一步实现的目的。




  上一篇: 使用nlsparam的一个例子   下一篇: 用SQL解决两道有趣的题(一)
li
 §相关评论  
 热点文章

·Resize datafile导致ASM Crash
·在Oracle10g RAC下新增ASM磁盘
·ORACLE SQL性能优化系列 (一)
·oracle性能调优:管理oracle日志
·oracle RAC环境中系统时钟的调
·why:Rac的心跳线不支持交叉线?
·RAC的VIP及实例依赖关系:版本O
·如何启动DataGuard的备用数据库
·系统表空间IO错误 数据损坏处理
·不幸中的万幸:遭遇ORA-00600 [
·用ORACLE的高级复制实现内外网
li
 编辑推荐
·Resize datafile导致ASM Crash
·在Oracle10g RAC下新增ASM磁盘
·ORACLE SQL性能优化系列 (一)
·oracle性能调优:管理oracle日志
·oracle RAC环境中系统时钟的调
·why:Rac的心跳线不支持交叉线?
·RAC的VIP及实例依赖关系:版本O
·如何启动DataGuard的备用数据库
·系统表空间IO错误 数据损坏处理
·不幸中的万幸:遭遇ORA-00600 [
·用ORACLE的高级复制实现内外网
li
 相关篇章
·使用nlsparam的一个例子
·用SQL实现99乘法表
·用SQL计算100以内的质数
·Oracle11g物理STANDBY应用日志时...
·缺少GROUP BY表达式可以顺利执行...
·ORA-21561错误
·临时表产生REDO过多的bug
·缺少GROUP BY表达式可以顺利执行...
·使用SQL判断一个数是否质数
·9i上使用CONNECT BY访问DUAL表的...
·用SQL解决两道有趣的题(一)
·RAC环境的STANDBY数据库备份报错
·2007年总结
·Oracle11g物理STANDBY打开模式应...
·Oracle11新特性——备份恢复功能...
·Oracle10g新增BLOCK CHANGE TRAC...
·ORA-600(ksmovrflow)错误
·RAC安装出现ORA-341和ORA-312错误
·撤销事务报错出现多个ORA-600错误
·Enterprise Linux 5上安装64位Or...
 
li
设为首页 | 关于我们 | 技术服务 | 收藏本站 | 网站地图 | 联系方式 | 本站友情连接