#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
Комментарии:
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. Понял. Дайте мне секунду подумать.