SQL Conundrum, как выбрать последнюю дату для части, но только 1 ряд на деталь (уникальный)
-
01-10-2019 - |
Вопрос
Я пытаюсь обернуть голову вокруг этого сегодня утром.
Я пытаюсь показать inventory
Статус для частей (для наших продуктов) и этот запрос становится только сложным, если я пытаюсь вернуть все детали.
Позвольте мне выложить это:
- однократный стол
inventoryReport
- У меня есть четкий список частей x, которые я хочу отображать, результат которого должен быть х # строк (1 ряд на деталь, показывающую новейшую запись в инвентаре).
- Таблица состоит из оттудатых записей изменений запасов (поэтому мне нужны только
LATEST
Дата запись на часть). - Все данные, содержащиеся в этой единственной таблице, поэтому нет необходимости.
В настоящее время на 1 одну часть, это довольно просто, и я могу выполнить это, сделав следующую SQL (чтобы дать вам некоторую идею):
SELECT TOP (1) ldDate, ptProdLine, inPart, inSite, inAbc, ptUm, inQtyOh + inQtyNonet AS in_qty_oh, inQtyAvail, inQtyNonet, ldCustConsignQty, inSuppConsignQty
FROM inventoryReport
WHERE (ldPart = 'ABC123')
ORDER BY ldDate DESC
Это заставляет меня мою верхнюю часть 1 строки, так проще на части, однако мне нужно показать все X (позволяет сказать 30 частей). Поэтому мне нужны 30 рядов, с этим результатом. Конечно, простое решение будет петли X # SQL вызовы в моем коде (но это было бы дорого), и это было бы достаточно, но для этой цели я хотел бы работать, чтобы этот SQL еще не понравился, чтобы уменьшить вызывы X # обратно в DB (если не нужно) до 1 запроса.
Из того, что я вижу здесь, мне нужно как-то отслеживать новейшую дату на предмет, ищете мой набор результатов.
Я в конечном итоге сделаю
WHERE ldPart in ('ABC123', 'BFD21', 'AA123', etc)
ограничить нужные части. Надеюсь, я сделал свой вопрос достаточно ясно. Дайте мне знать, если у вас есть идея. Я не могу сделать DISTINCT
Поскольку строки не совпадают, дата должна быть новейшей, и мне нужен максимум х строк.
Мысли? Я застрял...
Решение
РЕДАКТИРОВАТЬ: Обязательно проверьте производительность каждого раствора. Как указано в этот вопрос, Метод CTE может превзойти использование ROW_NUMBER.
;with cteMaxDate as (
select ldPart, max(ldDate) as MaxDate
from inventoryReport
group by ldPart
)
SELECT md.MaxDate, ir.ptProdLine, ir.inPart, ir.inSite, ir.inAbc, ir.ptUm, ir.inQtyOh + ir.inQtyNonet AS in_qty_oh, ir.inQtyAvail, ir.inQtyNonet, ir.ldCustConsignQty, ir.inSuppConsignQty
FROM cteMaxDate md
INNER JOIN inventoryReport ir
on md.ldPart = ir.ldPart
and md.MaxDate = ir.ldDate
Другие советы
SELECT *
FROM (SELECT i.*,
ROW_NUMBER() OVER(PARTITION BY ldPart ORDER BY ldDate DESC) r
FROM inventoryReport i
WHERE ldPart in ('ABC123', 'BFD21', 'AA123', etc)
)
WHERE r = 1
Вам нужно присоединиться к подпросию:
SELECT i.ldPart, x.LastDate, i.inAbc
FROM inventoryReport i
INNER JOIN (Select ldPart, Max(ldDate) As LastDate FROM inventoryReport GROUP BY ldPart) x
on i.ldPart = x.ldPart and i.ldDate = x.LastDate