我有一张如下表格。
`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)`
答案 0 :(得分:2)
通过使用递归WITH
。
请注意,我没有获得重复和所有排列,因此查询不会返回,例如1+2
和2+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。