返回求和列的所有10路(!!!)组合的SQL

时间:2017-05-23 17:11:39

标签: sql

忍受我,我正在接近这个想法,这是从我发布的这个问题开始的:

SQL that returns all the permutations of a summed column

因此,要重新哈希,假设我们有以下数据:

ID VALUE
-- -----
1  60
2  60
3  60
4  60

我想找到SUM到120的记录的所有排列。意思是,结果将是6行:

1 AND 2
1 AND 3
1 AND 4
--2 AND 1 (already used)
2 AND 3
2 AND 4
--3 AND 1 (already used)
--3 AND 2 (already used)
3 AND 4

在这些双向组合上提供的解决方案是执行自我加入。

但是,我认为解决方案不适用于我真正想要的东西:10路组合(对于不像我设计的例子那样容易求和的数据)。

这是否可行(使用一些简单的SQL)?

让我详细说明一下:

数据:

ID VALUE
-- -----
1  40
2  63
3  19
4  82
... and may more records

我正在寻找的结果(10条记录的所有组合至少达到300条):

就像第一个一样,它在哪里:

1 AND 2
1 AND 3
... etc

但是现在我们正在处理10,所以结果可能看起来像(预期总和> 300但<400):

ID1 DUR1 ID2 DUR2 ID3 DUR3 ... ID10 DUR10 SUMMED_TOTAL
--- ---- --- ---- --- ----     ---- ----- ------------
 1   40   2   63   3   19       23   8     312
 1   40   2   63   4   82       29   11    323

2 个答案:

答案 0 :(得分:2)

这是你想要做的吗?

select id1,id2
from (select t1.id as id1,t2.id as id2,
      count(*) over(partition by t1.id) as cnt,
      t1.val+sum(t2.val) over(partition by t1.id) as total
      from t t1
      join t t2 on t1.id<t2.id
     ) x
where cnt = 9 and total>=300

答案 1 :(得分:2)

您可以使用递归CTE执行此操作,这实际上执行上一个问题中使用的内部联接,但会不断重复联接,直到没有其他组合。

对于快速演示,我使用了(1,2,4,8,16,32,128)的值,因此对于1到255之间的任何数字,只有一个组合可以减少重复的行:

DECLARE @T TABLE (ID INT, Value INT);
INSERT @T (ID, Value) 
VALUES (1, 1), (2, 2), (3, 4), (4, 8), (5, 16), (6, 32), (7, 64), (8, 128);

WITH CTE AS
(   SELECT  ID,
            IDsUsed = CONVERT(VARCHAR(MAX), ID),
            Value,
            ValuesUsed = CONVERT(VARCHAR(MAX), Value),
            ItemCount = 1
    FROM    @T
    UNION ALL
    SELECT  T.ID,
            IDsUsed = CONVERT(VARCHAR(MAX), CONCAT(CTE.IDsUsed, ',', T.ID)),
            Value = CTE.Value + T.Value,
            ValuesUsed = CONVERT(VARCHAR(MAX), CONCAT(CTE.ValuesUsed, ',', T.Value)),
            ItemCount = ItemCount + 1
    FROM    CTE
            INNER JOIN @T AS T
                ON T.ID > CTE.ID
)
SELECT  IDsUsed, ValuesUsed, Value, ItemCount
FROM    CTE
WHERE   Value = 3

所以对于255你得到:

IDsUsed             ValuesUsed              Value       ItemCount
-----------------------------------------------------------------
1,2,3,4,5,6,7,8     1,2,4,8,16,32,64,128    255             8

3你会得到:

IDsUsed         ValuesUsed          Value       ItemCount
--------------------------------------------------------------
1,2             1,2                 3               2

修改

我想我可能误解了你的要求。如果你想要精确地找出总共10个组合,那么你需要准确地使用10个连接。它很长,但能给你你想要的东西。

SELECT  ID1 = t1.ID,
        Value1 = t1.Value,
        ID2 = t2.ID,
        Value2 = t2.Value,
        ID3 = t3.ID,
        Value3 = t3.Value,
        ID4 = t4.ID,
        Value4 = t4.Value,
        ID5 = t5.ID,
        Value5 = t5.Value,
        ID6 = t6.ID,
        Value6 = t6.Value,
        ID7 = t7.ID,
        Value7 = t7.Value,
        ID8 = t8.ID,
        Value8 = t8.Value,
        ID9 = t9.ID,
        Value9 = t9.Value,
        ID10 = t10.ID,
        Value10 = t10.Value,
        Total = t1.Value + t2.Value + t3.Value + t4.Value + t5.Value + 
                t6.Value + t7.Value + t8.Value + t9.Value + t10.Value
FROM    YourTable AS t1
        INNER JOIN YourTable AS t2
            ON t2.ID > t1.ID
        INNER JOIN YourTable AS t3
            ON t3.ID > t2.ID
        INNER JOIN YourTable AS t4
            ON t4.ID > t3.ID
        INNER JOIN YourTable AS t5
            ON t5.ID > t4.ID
        INNER JOIN YourTable AS t6
            ON t6.ID > t5.ID
        INNER JOIN YourTable AS t7
            ON t7.ID > t6.ID
        INNER JOIN YourTable AS t8
            ON t8.ID > t7.ID
        INNER JOIN YourTable AS t9
            ON t9.ID > t8.ID
        INNER JOIN YourTable AS t10
            ON t10.ID > t9.ID