2016-08-22 80 views
0

我真的很困惑如何将这些组分成子组。这是2个订单的示例(超出〜5M)SQL Server 2012中,秩()和SUM()结束()直到条件

  • 订单可能有一个或多个“分组项目”。
  • 组编号= SUM(ItemQuantity)。
  • 组通过OrderLine订购

例如,在下面的表中,我们看到一组“3” &两组“2”的

OrderNo OrderLine GroupNo ItemQty 
10496  1   3  1  =3 
10496  2   3  1  =3 
10496  3   3  1  =3 
10496  4   2  1  =2(1) 
10496  5   2  1  =2(1) 
10496  6   2  1  =2(2) 
10496  7   2  1  =2(2) 

等级()& DENSE_RANK不解决该问题,因为有同组的倍数,OrderLines是不同的。

我会加入到另一个表到最后,但我想是一种方法来区分相同的组。也许通过添加一个“子组”字段。

OrderNo OrderLine GroupNo ItemQty Subgroup 
10496  1   3  1  300 
10496  2   3  1  300 
10496  3   3  1  300 
10496  4   2  1  201 
10496  5   2  1  201 
10496  6   2  1  202 
10496  7   2  1  202 

测试下方

CREATE TABLE #temptable( 
     OrderNo varchar(5), 
     OrderLine int, 
     GroupNo int, 
     ItemQty int); 

    INSERT INTO #temptable (OrderNo,OrderLine,GroupNo,ItemQty) 
    VALUES 
    ('10496','1','3','1'), 
    ('10496','2','3','1'), 
    ('10496','3','3','1'), 
    ('10495','1','4','1'), 
    ('10495','2','4','2'), 
    ('10495','3','4','1'), 
    ('10495','4','2','1'), 
    ('10495','5','2','1'), 
    ('10495','6','3','1'), 
    ('10495','7','3','2'), 
    ('10495','8','2','1'), 
    ('10495','9','2','1'), 
    ('10495','10','2','1'), 
    ('10495','11','2','1'), 
    ('10495','12','2','1'), 
    ('10495','13','2','1'); 

一个DO WHILE

SUM(ItemQty)Over(Partition by OrderNo,GroupNo Order by OrderLine) >= GroupNo 

可以工作,但它需要在每一个订单的每个组中运行。

然后我开始使用XML路径来查询每一行,但它真的不会有效。

SELECT distinct t1.OrderNo,t1.GroupNo, 
     STUFF(( SELECT ',' + QUOTENAME(t2.OrderLine) 
        FROM #temptable t2 
        WHERE 
        t2.OrderNo = t1.OrderNo AND t2.GroupNo = t1.GroupNo 
        Order by t2.OrderLine Asc 
        FOR XML PATH(''),TYPE 
        ).value('.', 'NVARCHAR(MAX)') ,1,1,'') 
     AS [Rows] 
    FROM #temptable t1 
    Order by t1.OrderNo,t1.GroupNo 
+0

你想要做什么以及最终的预期产出是什么? – TheGameiswar

+0

在你的例子中,所有订单都有'10496' OrderNo,我认为它们必须是'10496'和'10495' – Backs

+0

是不是唯一的'OrderNo + GroupNo'? (连接为字符串) –

回答

0

以@ Nick.McDermaid是关于这里的mod %建议一个解决方案,诚然它可以改进,但现在它会工作了。

With a as (
    select OrderNo,OrderLine,GroupNo,ItemQty 
    ,CASE 
    WHEN SUM(ItemQty)Over 
    (Partition by OrderNo,GroupNo Order by OrderNo,OrderLine) % GroupNo=1 
    THEN GroupNo*100 
    ELSE NULL END as SG 
    from #temptable) 

    Select a.OrderNo,a.OrderLine,a.ItemQty,a.GroupNo 
    ,MAX(a.SG2)Over(Partition by a.OrderNo,a.GroupNo Order by a.OrderNo,a.OrderLine ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as Subgroup 
    from 
     (Select OrderNo,OrderLine,GroupNo,ItemQty 
     ,CASE WHEN SG IS NULL THEN NULL ELSE SG+RANK()Over(Partition by OrderNo,SG Order by OrderNo,OrderLine) END as SG2 
     from a)a 
    Order by a.OrderNo,a.OrderLine;