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

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


第一个问题:

已知两个1~30之间的数字,甲知道两数之和,乙知道两数之积。

甲问乙:"你知道是哪两个数吗?"乙说:"不知道"

乙问甲:"你知道是哪两个数吗?"甲说:"也不知道"

于是,乙说:"那我知道了"

随后甲也说:"那我也知道了"

这两个数是什么?

先给出SQL解,然后简单描述一下。

这道题分两种情况,两个数不重复,那么有两个可能结果:

SQL> WITH
2 T AS
3 (SELECT ROWNUM NUM FROM DUAL CONNECT BY LEVEL <= 30)
4 SELECT A, B
5 FROM
6 (
7 SELECT
8 A,
9 B,
10 TOTAL,
11 MUL,
12 COUNT(*) OVER (PARTITION BY MUL) MUL_P
13 FROM
14 (
15 SELECT
16 A,
17 B,
18 TOTAL,
19 MUL,
20 COUNT(*) OVER (PARTITION BY TOTAL) TOTAL_P
21 FROM
22 (
23 SELECT
24 A.NUM A,
25 B.NUM B,
26 A.NUM B.NUM TOTAL,
27 A.NUM * B.NUM MUL,
28 COUNT(*) OVER (PARTITION BY A.NUM * B.NUM) MUL_P
29 FROM T A, T B
30 WHERE A.NUM < B.NUM
31 )
32 WHERE MUL_P != 1
33 )
34 WHERE TOTAL_P != 1
35 )
36 WHERE MUL_P = 1
37 ;

A B
---------- ----------
1 6
1 8

如果两个数是可以重复的,那么有唯一的答案:

SQL> WITH
2 T AS
3 (SELECT ROWNUM NUM FROM DUAL CONNECT BY LEVEL <= 30)
4 SELECT A, B
5 FROM
6 (
7 SELECT
8 A,
9 B,
10 TOTAL,
11 MUL,
12 COUNT(*) OVER (PARTITION BY MUL) MUL_P
13 FROM
14 (
15 SELECT
16 A,
17 B,
18 TOTAL,
19 MUL,
20 COUNT(*) OVER (PARTITION BY TOTAL) TOTAL_P
21 FROM
22 (
23 SELECT
24 A.NUM A,
25 B.NUM B,
26 A.NUM B.NUM TOTAL,
27 A.NUM * B.NUM MUL,
28 COUNT(*) OVER (PARTITION BY A.NUM * B.NUM) MUL_P
29 FROM T A, T B
30 WHERE A.NUM <= B.NUM
31 )
32 WHERE MUL_P != 1
33 )
IXDBA.NET社区论坛
34 WHERE TOTAL_P != 1
35 )
36 WHERE MUL_P = 1
37 ;

A B
---------- ----------
1 4

下面简单描述一下思路:

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

最内层的循环构造两个数的笛卡儿积,列出所有的可能,不过对于我们来说,A1B2A2B1没有区别,因此加上限制条件A > B。上面两个SQL唯一的区别就在这里,如果两个数是可以重复的那么A >= B,否则A > B

循环中的分析函数用来计算AB乘积相同的个数,如果这个数是1,说明这两个数是可以确定的。而根据乙的描述,他并不知道这两个数是什么,因此这部分应该是可以被排除的。

第二层的循环道理相同,这里排除的是A所不知道的,两个数和能确定这两个数的部分。

到了第三层,乙知道AB是什么数了,说明这个时候AB的积已经是唯一的。




  上一篇: 用SQL解决两道有趣的题(二)   下一篇: RAC环境的STANDBY数据库备份报错
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
 相关篇章
·用SQL解决两道有趣的题(二)
·使用nlsparam的一个例子
·用SQL实现99乘法表
·用SQL计算100以内的质数
·Oracle11g物理STANDBY应用日志时...
·缺少GROUP BY表达式可以顺利执行...
·ORA-21561错误
·临时表产生REDO过多的bug
·缺少GROUP BY表达式可以顺利执行...
·使用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...
·安装ORACLE10201 for ENTERPRISE...
 
li
设为首页 | 关于我们 | 技术服务 | 收藏本站 | 网站地图 | 联系方式 | 本站友情连接