所有可能的组合都不透明

时间:2012-10-22 17:52:55

标签: sql sql-server-2012

我一直在研究一个我无法弄清楚的问题。我尝试过不同的交叉连接,CTE,窗口函数等组合,但却无法完全实现。我也不想去动态SQL路线。有人可以帮忙吗?

给定一组可变的分组值,可以垂直生成所有可能的组合(派生组,值)

其他信息:

  1. 无论如何,2个组合都应具有相同的值集 订购。示例:如果您已经有(1,2)则不生成(2,1), 如果(1,2,3)则没有(1,3,2),(2,1,3),(2,3,1),(3,1,2),(3,2,1)< / LI>
  2. 同一组的值不应合并
  3. 所有值都是唯一的,无论组如何。唯一的原因 初始分组是应用规则#2
  4. 实施例: 给出

    的起始组和值

    输入组值

    • 1 8
    • 2 7
    • 2 9
    • 3 1
    • 3 6
    • 3 3

    生成此输出

    输出组值

    • 1 8
    • 2 7
    • 3 9
    • 4 1
    • 5 6
    • 6 3
    • 7 8
    • 7 7
    • 8 8
    • 8 9
    • 9 8
    • 9 1
    • 10 8
    • 10 6
    • 11 8
    • 11 3
    • 12 7
    • 12 1
    • 13 7
    • 13 6
    • 14 7
    • 14 3
    • 15 9
    • 15 1
    • 16 9
    • 16 6
    • 17 9
    • 17 3
    • 18 8
    • 18 7
    • 18 1
    • 19 8
    • 19 7
    • 19 6
    • 20 8
    • 20 7
    • 20 3
    • 21 8
    • 21 9
    • 21 1
    • 22 8
    • 22 9
    • 22 6
    • 23 8
    • 23 9
    • 23 3

    这是用于产生输出的手动非垂直方法

    CREATE TABLE #temp1 (GroupID INT, MyValue INT)
    
    INSERT INTO #temp1 (GroupID, MyValue)
    VALUES  (1,8),(2,7),(2,9),(3,1),(3,6),(3,3)
    
    --1st set of possibilities
    SELECT MyValue
    FROM #temp1
    
    --2nd set of possibilities
    SELECT a.MyValue, b.MyValue
    FROM #temp1 a
    JOIN #temp1 b
    ON a.GroupID < b.GroupID
    
    --3rd set
    SELECT a.MyValue, b.MyValue, c.MyValue
    FROM #temp1 a
    JOIN #temp1 b
    ON a.GroupID < b.GroupID
    JOIN #temp1 c
    ON b.GroupID < c.GroupID
    
    DROP TABLE #temp1 
    

    我的问题是可以有可变数量的起始值 考虑到这一点,我的输出需要在分组垂直集中,所以我只返回2列。 1将数字组合在一起,数字本身。 对于这个具体的例子,应该有46行,23个不同的组,如上所示

    我写了CTE,我一直在修改并最终报废:

    WITH    MyCTE
              AS (SELECT    1 AS Level, DENSE_RANK() OVER (ORDER BY GroupID, MyValue) AS DgroupID, GroupID, MyValue
                  FROM      #temp1
                  UNION ALL
                  SELECT    a.Level + 1, DENSE_RANK() OVER (ORDER BY b.GroupID, b.MyValue), b.GroupID, b.MyValue
                  FROM      MyCTE a
                  JOIN      #temp1 b
                            ON a.GroupID < b.GroupID)
    
    SELECT  DENSE_RANK() OVER (ORDER BY Level, DgroupID), MyValue
    FROM    MyCTE 
    

    明显的问题:

    1)我用来为每行提供增量值的窗口函数没有按预期工作。这可能是由于CTE的工作方式。表现好,对我不好。 ROW_NUMBER窗口函数执行相同的操作。我想要做的就是在每次迭代中自动增量行,这样我就可以在表格“不透明”时识别出该组。我相信CTE如此之快的原因是因为它们实际上是基于集合的操作,因此即使存在递归,我也不能依赖循环/迭代模式来产生预期结果。在我的所有假设中随意纠正我

    2)不动产。我需要获取一组行并将列展开成行,每个行保留原始行的标识符以显示它们被组合在一起。 SQL Server有一个很棒的命令,名为UNPIVOT,它根本不能帮助我,因为你需要知道在设计时你有多少列没有被删除。这一点的重点是能够提供可变数量的输入并产生可预测的输出

1 个答案:

答案 0 :(得分:0)

因此,您尝试将所有“组1”值与所有“组2”值和所有“组3”值组合在一起,但是如前所述,防止重复项:1,2和2,1。你的手动方法看起来没问题,但是我不明白为什么你要比较组而不是“值”小于先前的那样...

SELECT a.MyValue, b.MyValue
FROM #temp1 a
JOIN #temp1 b
ON a.MyValue < b.MyValue AND a.GroupID <> b.GroupID

--3rd set
SELECT a.MyValue, b.MyValue, c.MyValue
FROM #temp1 a
JOIN #temp1 b
ON a.MyValue < b.MyValue AND a.GroupID <> b.GroupID 
JOIN #temp1 c
ON b.MyValue < c.MyValue AND a.GroupID <> c.GroupID AND b.GroupID <> c.GroupID

根据您的反馈,上述调整应该有效,只需要花费额外的力量,因为它必须渗透到第1组,第2组以及第2组,第1组,因为第1组可能存在于第2组,但是第1组的数字为5,如果你总是要求a.Group小于b.Group,你将永远不会在第一个位置获得值1,因为第2组大于第1组。

这对你的场景有意义吗?