SQL用于计算列中所有可能数字组合的总和

时间:2014-12-08 22:41:16

标签: sql oracle

我有一张如下表格。

`Col (number)
1
2
4
8
`

我正在寻找一个SQL,它会给我一个如下输出,总结多行中列的所有不同值组合。

`3 (1+2)
5 (1+4)
9 (1+8)
....
....
7(1+2+4)
11(1+2+8)
14(2+4+8)
15(1+2+4+8)`

2 个答案:

答案 0 :(得分:2)

通过使用递归WITH

,这对我来说很有用

请注意,我没有获得重复和所有排列,因此查询不会返回,例如1+22+1,因为它们是相同的。

我们将每个唯一组合作为Varchar2(在下面重命名为expression),然后简单地从Varchar2中提取数字(如创建行,其值由字符{ {1}})然后获取+

我选择由SUM排序的row_number(),这样结果将按顺序显示,从1到最后一个数字,无论它们在数据库中的插入顺序如何。

另一个问题是,如果表中的数字不唯一,则会生成重复数据。因此,只有在数字表中没有重复项时,这才有效。如果您的表中有重复项,解决此问题的一种方法是在查询中添加val子句(我已在下面的代码中添加它以供参考)

这可能不是最好的解决方案,而且我确信可能有更好的选择,但这是我能在短时间内提出的。

尝试一下:

distinct

SELECT distinct expression, ( SELECT SUM (REGEXP_SUBSTR (expression, '[^+]+', 1, LEVEL)) FROM DUAL CONNECT BY REGEXP_SUBSTR (expression, '[^+]+', 1, LEVEL) IS NOT NULL) AS THE_SUM FROM (WITH t AS ( SELECT ROW_NUMBER () OVER (ORDER BY val) AS seqno, val AS expression FROM my_numbers ORDER BY val ASC), t2 (s, t) AS (SELECT seqno, CAST (expression AS VARCHAR2 (1)) FROM t UNION ALL SELECT t.seqno, t || '+' || expression FROM t, t2 WHERE s < seqno) SELECT s, t expression FROM t2) ORDER BY 1 表的内容:

VAL
4
8
2
1

输出:

EXPRESSION     |     THE_SUM
1              |     1
1+2            |     3
1+2+4          |     7
1+2+4+8        |     15
1+2+8          |     11
1+4            |     5
1+4+8          |     13
1+8            |     9
2              |     2
2+4            |     6
2+4+8          |     14
2+8            |     10
4              |     4
4+8            |     12
8              |     8

答案 1 :(得分:1)

Oracle 11gR2支持递归CTES,因此可以表示为:

with nums as (
      select 1 as n union all select 10 union all select 100 union all select 1000
     ),
     t(n, vals, cnt) as (
      select n, cast(n as varchar(255)) as vals, 1 as cnt
      from nums
      union all
      select t.n + nums.n, cast(vals || '+' || nums.n as varchar(255)), cnt + 1
      from t join
           nums
           on nums.n > t.n 
     )
 select *
 from t;

使用connect by可能有类似的方法,但我更熟悉递归CTE。