【问题标题】:SQL Server 2012, Rank() & SUM() Over() Until conditionSQL Server 2012,Rank() & SUM() Over() 直到条件
【发布时间】:2016-12-28 12:25:56
【问题描述】:

我真的很困惑如何将这些组划分为子组。这是 2 个订单的示例(共约 5M)

  • 一个订单可能有 1 个或多个“分组项目”。
  • 组号 = 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)

Rank() 和 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');

做的时候

    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

【问题讨论】:

  • 你想做什么,最终的预期输出是什么?
  • 在您的示例中,所有订单都有10496 OrderNo,我认为,它们必须是1049610495
  • 唯一组不就是OrderNo + GroupNo吗? (连接为字符串)
  • @Nick.McDermaid Concat(OrderNO,GroupNo) 将所有GroupNo 分组,但我们在某些订单上有多个GroupNo=2。这些需要细分,这就是我遇到的问题。
  • 所以...订单行 4 和 5 是一组 2,订单行 6 和 7 是另一组吗?所以我们总是可以假设订单行组合在一起(即 4 和 6 不是一组?)

标签: sql-server tsql sql-server-2012 common-table-expression


【解决方案1】:

采纳@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;

【讨论】:

    猜你喜欢
    • 2021-06-01
    • 1970-01-01
    • 2011-06-12
    • 1970-01-01
    • 1970-01-01
    • 2022-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多