达梦数据库的递归WITH特性研究

题目:一个布袋中装有数量相同的四种颜色的小球。随机从布袋中取四次,每次取完都放回去。现在问四次结果总颜色数等于3的概率是多少?
题目很短,实现起来比较困难,尤其是只能用一条SQL来实现的时候,就更难了。
不过,利用递归WITH的特性,确实在Oracle中可以用单条语句实现。
我今天想分享的主题是,这么复杂的SQL达梦数据库也同样可以支持,只是要注意一些版本和参数方面的问题。

SQL语句实现如下:

WITH
t AS
(
SELECT
ROWNUM rn – 先构造一个1,2,3,4的结果集,每个rn表示一种颜色
FROM
DUAL CONNECT BY ROWNUM<=4
)
,
t2 AS
( ---- 集合t2模拟独立取四次的动作,最终结果会有4444=256行
SELECT
ROWNUM id ---- 构造唯一ID供下面拆分用
,
REPLACE(SYS_CONNECT_BY_PATH(rn, ‘@’), ‘@’) path---- 用一个特殊字符@来作分隔符,
---- 并在最后用REPLACE把它去除
,
COUNT(
) OVER() cnt ---- 利用分析函数算出总行数并把它作为一个列返回
FROM
t ---- 这个是有四行的集合
WHERE
LEVEL =4 ---- 我们需要的仅仅是最后一层的结果。在PATH里面已经包含了取四次的所有结果组合
CONNECT BY LEVEL<=4 ---- 没有任何条件,前后都是独立的
)
,
t3 AS
( ---- 集合t3把t2中的PATH包含的颜色组合拆开为四行
SELECT
id ,
cnt,
SUBSTR(PATH, rn, 1) color
FROM
t2,
(
SELECT ROWNUM rn FROM DUAL CONNECT BY ROWNUM<=4
)
– 笛卡尔积,用于把t2中的一行变为四行
)
,
t4 AS
(
SELECT
id,
cnt
FROM
t3
GROUP BY
id,
cnt
HAVING COUNT(DISTINCT color)=3 — 每一个id中包含三种不同颜色
)
SELECT COUNT(*)/MAX(CNT) AS prob FROM T4;

达梦数据库中也支持递归WITH调用这个语法,并且算出了同样的结果

不过调试过程中发现两个问题

  1. 较低的版本无法支持,会报错:【-839】BDATA_SIZE不允许为1
    检查发现这个BDATA_SIZE的取值是1000,并没有问题。i应该是版本不支持这个写法。

2.DM7最新的版本下载后运行后,不报错,不过得出的结果有一些问题

DM的calc_as_decimal参数要调整,从0调整为1,否则整除相除成整数

SQL> select para_name ,para_value from v$dm_ini where para_name=‘CALC_AS_DECIMAL’;
行号 PARA_NAME PARA_VALUE


1 CALC_AS_DECIMAL 0

调整这个参数为1后,得出了所要的结果

SQL> WITH
2 t AS
3 (
4 SELECT
5 ROWNUM rn – 先构造一个1,2,3,4的结果集,每个rn表示一种颜色
6 FROM
7 DUAL CONNECT BY ROWNUM<=4
8 )
9 ,
10 t2 AS
11 ( ---- 集合t2模拟独立取四次的动作,最终结果会有4444=256行
12 SELECT
13 ROWNUM id ---- 构造唯一ID供下面拆分用
14 ,
15 REPLACE(SYS_CONNECT_BY_PATH(rn, ‘@’), ‘@’) path---- 用一个特殊字符@来作分隔符,
16 ---- 并在最后用REPLACE把它去除
17 ,
18 COUNT(
) OVER() cnt ---- 利用分析函数算出总行数并把它作为一个列返回
19 FROM
20 t ---- 这个是有四行的集合
21 WHERE
22 LEVEL =4 ---- 我们需要的仅仅是最后一层的结果。在PATH里面已经包含了取四次的所有结果组合
23 CONNECT BY LEVEL<=4 ---- 没有任何条件,前后都是独立的
24 )
25 ,
26 t3 AS
27 ( ---- 集合t3把t2中的PATH包含的颜色组合拆开为四行
28 SELECT
29 id ,
30 cnt,
31 SUBSTR(PATH, rn, 1) color
32 FROM
33 t2,
34 (
35 SELECT ROWNUM rn FROM DUAL CONNECT BY ROWNUM<=4
36 )
37 – 笛卡尔积,用于把t2中的一行变为四行
38 )
39 ,
40 t4 AS
41 (
42 SELECT
43 id,
44 cnt
45 FROM
46 t3
47 GROUP BY
48 id,
49 cnt
50 HAVING COUNT(DISTINCT color)=3 — 每一个id中包含三种不同颜色
51 )
52 SELECT COUNT(*)/MAX(CNT) AS prob FROM T4;

行号 PROB


1 0.5625

已用时间: 4.636(毫秒). 执行号:7.
SQL>

达梦数据库知识总结链接贴

你可能感兴趣的:(达梦)