Найти самую последнюю строку группы

#sql #sql-server-2008-r2

#sql #sql-server-2008-r2

Вопрос:

Я знаю, что нет «последней» строки, поэтому, надеюсь, мне ясно, что это не то, что я действительно ищу. Я хочу выбрать строки в таблице, если значение одного конкретного поля является последним в алфавитном порядке. Я постараюсь сделать все возможное, чтобы нарисовать это ниже. Я немного новичок, поэтому, пожалуйста, потерпите меня…

ТАБЛИЦА [Номер заказа], [Дата поставки], [Кол-во заказов], [Кол-во отгруженных товаров], [Счет на], [Отгрузка на], [Номер накладной]

Много раз мы переоформляем счета-фактуры, и номер счета-фактуры увеличивается на букву. Это также обновит дополнительные значения полей. Ниже приведен типичный набор с кратными счетами-фактурами…

 '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 - 
  

Что мне нужно, так это запросить все вышеуказанные поля и вернуть только те, где [Номер счета] является последним (в алфавитном порядке) (в данном случае 987654D), но также СУММИРОВАТЬ значения [Количество заказов] и [Количество отгруженных] для всех записей независимо от [Счет-фактураЧисло].

Если я могу предоставить какую-либо дополнительную информацию, пожалуйста, дайте мне знать. Заранее благодарю вас.

Комментарии:

1. Является ли исходный номер счета-фактуры без буквы или всегда «A»?

2. Исходный номер накладной всегда A. Номер накладной всегда будет номером заказа с буквой после него. Если это поможет.

Ответ №1:

Можно использовать ROW_NUMBER функцию для получения последней строки в группе, установив значение по ORDER BY убыванию, а затем с помощью фильтра получить строку со значением 1. SUM И MAX с помощью windowing помогают получить другие совокупные значения.

 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

Комментарии:

1. Это решение работает для меня! Большое вам спасибо. Я пытался получить это всю неделю. Теперь мне просто нужно понять, что происходит в запросе. Это мой первый вопрос. Что мне нужно сделать, чтобы проголосовать или отдать должное, или как бы это ни работало?

Ответ №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 
  

Комментарии:

1. Позвольте мне попробовать.

2. В результате я получаю 3 строки. В нем отсутствует строка счета-фактуры.

Ответ №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];
  

Вы можете добавить больше столбцов из общей накладной, поместив их в список ВЫБОРА из t1, как я сделал с [Отправить в] .

РЕДАКТИРОВАТЬ 1: добавлена группировка, поэтому рассматривается вся таблица. Честно говоря, Мартин К. опубликовал этот ответ первым.

Комментарии:

1. Позвольте мне попробовать.

2. Я пропустил предложение where, потому что мне это понадобится для всех записей. Я также добавил дополнительные поля, такие как [Отправить в], и я все еще получаю несколько строк на счет. Мне понадобились бы только значения полей для общего (в этом примере) или «последнего» счета в алфавитном порядке, но СУММА всех счетов.

3. Я вижу. СУММА всех счетов с одинаковым номером заказа, правильно?

4. Точно. СУММА всех накладных с одинаковым номером заказа, но также и с другими полями, такими как [Отправить в] из «последней» (в данном случае общей накладной) строки. Эти нечисловые поля также изменяются в счетах-фактурах, поэтому мне нужен «последний».

5. Понял. Дайте мне секунду подумать.