【问题标题】:Find the most recent row of a group查找组的最新行
【发布时间】:2014-06-27 12:46:46
【问题描述】:

我知道没有“最后”行,所以我希望我清楚这不是我真正想要的。如果一个特定字段的值是按字母顺序排列的最后一个,我想选择表中的行。下面我尽量画出来。我是个新手,所以请多多包涵……

表 [订单编号]、[交货日期]、[订单数量]、[发货数量]、[开单方]、[发货方]、[发票编号]

我们会多次重新开具发票,发票编号会增加一个字母。这也将更新其他字段值。以下是带有多张发票的典型集合...

'987654', '2014-05-01 00:00:00', '100',  '90',  'BillToXYZ', 'ShipToXYZ',               '987654A' - NEW RECORD - 
'987654', '2014-05-01 00:00:00', '-100', '-90', 'BillToXYZ', 'ShipToXYZ',               '987654B' - NEW RECORD - 
'987654', '2014-05-01 00:00:00', '100',  '100', 'BillToXYZ', 'ShipToNEWSHIPTOLOCATION', '987654C' - NEW RECORD - 
'987654', '2014-05-01 00:00:00', '10',   '10',  'BillToXYZ', '2ndNEWSHIPTOLOCATION',    '987654D' - NEW RECORD - 

我需要的是查询上述所有字段,只带回那些 [Invoice Number] 是最后一个(按字母顺序)(在本例中为 987654D)的字段,但还要将其 SUM [Order Qty] 的值和无论[发票编号]如何,所有记录的[已发货数量]。

如果我可以提供任何其他信息,请告诉我。提前谢谢你。

【问题讨论】:

  • 原始发票号码是没有字母还是总是'A'?
  • 原始发票编号始终为 A。发票编号始终为订单编号,后跟一个字母。如果有帮助的话。

标签: sql sql-server-2008-r2


【解决方案1】:

可以使用ROW_NUMBER 函数获取组中的最后一行,设置ORDER BY 降序,然后使用过滤器获取值为1 的行。 带有窗口的SUMMAX 有助于获取其他聚合值。

WITH D AS (
  SELECT [Order Number]
       , [Delivery Date]
       , SUM([Order Qty]) OVER (PARTITION BY [Order Number]) [Total Order Qty]
       , [Total Shipped Qty] 
       = SUM([Shipped Qty]) OVER (PARTITION BY [Order Number]) 
       , [Bill To]
       , [Ship To]
       , [Last Invoice Number] 
       = MAX([Invoice Number]) OVER (PARTITION BY [Order Number])
       , ID = ROW_NUMBER() OVER (PARTITION BY [Order Number] 
                                 ORDER BY [Invoice Number] DESC)
  FROM   Table1
)
SELECT [Order Number]
     , [Delivery Date]
     , [Total Order Qty]
     , [Total Shipped Qty]
     , [Bill To]
     , [Ship To]
     , [Last Invoice Number]
FROM   D
WHERE  ID = 1

SQLFiddle demo

【讨论】:

  • 这个解决方案对我有用!非常感谢。我整个星期都在努力做到这一点。现在我只需要了解查询中发生了什么。这是我的第一个问题。我必须做什么才能投票或给予信任,或者不管它如何工作?
【解决方案2】:

在我看来,您可以按照其他答案的建议使用 GROUP BY 和聚合,但将其放在子查询中,以便您可以将“主”表链接到它并获取最新发票的详细值。以下代码是否符合您的要求?

CREATE TABLE #Table 
  (
    OrderNumber int, 
    DeliveryDate datetime, 
    OrderQty int, 
    ShippedQty int , 
    BillTo varchar(10), 
    ShipTo varchar(100), 
    InvoiceNumber varchar(20)
  )

INSERT INTO #Table 
  (
    OrderNumber, 
    DeliveryDate, 
    OrderQty, 
    ShippedQty, 
    BillTo, 
    ShipTo, 
    InvoiceNumber
  )

SELECT '987654', '2014-05-01 00:00:00', '100',  '90',  'BillToXYZ', 'ShipToXYZ',               '987654A' UNION
SELECT '987654', '2014-05-01 00:00:00', '-100', '-90', 'BillToXYZ', 'ShipToXYZ',               '987654B' UNION
SELECT '987654', '2014-05-01 00:00:00', '100',  '100', 'BillToXYZ', 'ShipToNEWSHIPTOLOCATION', '987654C' UNION
SELECT '987654', '2014-05-01 00:00:00', '10',   '10',  'BillToXYZ', '2ndNEWSHIPTOLOCATION',    '987654D'


SELECT t.*, s.TotalOrderQty, s.TotalShippedQty
FROM 
    #Table t
     INNER JOIN 
      (
        SELECT 
            OrderNumber, 
            MAX(InvoiceNumber) LastInvoice, 
            SUM(OrderQty) TotalOrderQty, 
            SUM(ShippedQty) TotalShippedQty
        FROM #Table
        GROUP BY OrderNumber
      ) s ON 
        t.OrderNumber = s.OrderNumber AND
        t.InvoiceNumber = s.LastInvoice

DROP TABLE #Table 

【讨论】:

  • 让我试一试。
  • 这给了我 3 行作为结果。它省略了 A 发票行。
【解决方案3】:

这就是你想要的吗?

编辑 2: 得到 OP 的澄清。已编辑我的解决方案以显示完整订单的聚合,但仅显示最新发票的行项目信息。在这里摆弄:http://sqlfiddle.com/#!3/08bb0/6

SELECT t1.[Order Number],
       t2.[Max Invoice Number],
       t1.[Ship To],
       t2.[Sum Order Qty],
       t2.[Sum Shipped Qty]
FROM Table1 t1 INNER JOIN
     (SELECT    [Order Number],
                MAX([Invoice Number] ) AS [Max Invoice Number],
                SUM([Order Qty]) AS [Sum Order Qty],
                SUM([Shipped Qty]) AS [Sum Shipped Qty]   
      FROM     Table1
      GROUP BY [Order Number]) t2
      ON t1.[Invoice Number] = t2.[Max Invoice Number]
ORDER BY t1.[Order Number];

您可以从 D 发票中添加更多列,方法是把它们放在 t1 的 SELECT 列表中,就像我对 [Ship To] 所做的那样。

编辑 1: 添加了分组以便考虑整个表。公平地说,Martin K. 首先发布了这个答案。

【讨论】:

  • 让我试一试。
  • 我省略了 where 子句,因为所有记录都需要它。我还添加了 [Ship To] 等附加字段,但每张发票仍然有多行。我只需要 D(在本例中)或“最后”按字母顺序发票的字段值,但需要所有发票的总和。
  • 我明白了。具有相同订单号的所有发票的总和,对吗?
  • 没错。具有相同订单号的所有发票的总和,以及“最后一个”(在本例中为 D 发票)行中的 [Ship To] 等其他字段。这些非数字字段也会在发票上发生变化,这就是我想要“最后一个”的原因。
  • 知道了。给我一点时间思考。
猜你喜欢
  • 2021-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-04
  • 1970-01-01
  • 2021-05-15
  • 1970-01-01
相关资源
最近更新 更多