SQL Server: SELECT только строки с MAX (DATE)
У меня есть таблица данных (db - MSSQL):
ID OrderNO PartCode Quantity DateEntered
417 2144 44917 100 18-08-11
418 7235 11762 5 18-08-11
419 9999 60657 100 18-08-11
420 9999 60657 90 19-08-11
Я хотел бы сделать запрос, который возвращает OrderNO, PartCode и Quantity, но только для последнего зарегистрированного заказа.
В таблице примеров я хотел бы получить следующую информацию:
OrderNO PartCode Quantity
2144 44917 100
7235 11762 5
9999 60657 90
Обратите внимание, что для заказа 9999 была возвращена только одна строка.
Спасибо!
Ответы
Ответ 1
Если rownumber() over(...)
доступен для вас....
select OrderNO,
PartCode,
Quantity
from (select OrderNO,
PartCode,
Quantity,
row_number() over(partition by OrderNO order by DateEntered desc) as rn
from YourTable) as T
where rn = 1
Ответ 2
Лучший способ - Микаэль Эрикссон, если ROW_NUMBER()
доступен вам.
Следующее лучше всего - присоединиться к запросу, как ответ Cularis.
В качестве альтернативы самым простым и прямым способом является коррелированный суб-запрос в предложении WHERE.
SELECT
*
FROM
yourTable AS [data]
WHERE
DateEntered = (SELECT MAX(DateEntered) FROM yourTable WHERE orderNo = [data].orderNo)
Или...
WHERE
ID = (SELECT TOP 1 ID FROM yourTable WHERE orderNo = [data].orderNo ORDER BY DateEntered DESC)
Ответ 3
select OrderNo,PartCode,Quantity
from dbo.Test t1
WHERE EXISTS(SELECT 1
FROM dbo.Test t2
WHERE t2.OrderNo = t1.OrderNo
AND t2.PartCode = t1.PartCode
GROUP BY t2.OrderNo,
t2.PartCode
HAVING t1.DateEntered = MAX(t2.DateEntered))
Это самый быстрый из всех запросов, указанных выше. Стоимость запроса составила 0,0070668.
Предпочтительный ответ выше, Mikael Eriksson, имеет стоимость запроса 0,0146625
Вы можете не заботиться о производительности для такого небольшого образца, но в больших запросах все это добавляется.
Ответ 4
SELECT t1.OrderNo, t1.PartCode, t1.Quantity
FROM table AS t1
INNER JOIN (SELECT OrderNo, MAX(DateEntered) AS MaxDate
FROM table
GROUP BY OrderNo) AS t2
ON (t1.OrderNo = t2.OrderNo AND t1.DateEntered = t2.MaxDate)
Внутренний запрос выбирает все OrderNo
с максимальной датой. Чтобы получить другие столбцы таблицы, вы можете присоединиться к ним на OrderNo
и MaxDate
.
Ответ 5
Для MySql вы можете сделать что-то вроде следующего:
select OrderNO, PartCode, Quantity from table a
join (select ID, MAX(DateEntered) from table group by OrderNO) b on a.ID = b.ID
Ответ 6
И вы также можете использовать этот оператор select как левый запрос соединения...
Пример:
... left join (select OrderNO,
PartCode,
Quantity from (select OrderNO,
PartCode,
Quantity,
row_number() over(partition by OrderNO order by DateEntered desc) as rn
from YourTable) as T where rn = 1 ) RESULT on ....
Надеюсь, что это поможет кому-то, кто ищет это:)
Ответ 7
Попробуйте избежать использования IN JOIN
SELECT SQL_CALC_FOUND_ROWS * FROM (SELECT msisdn, callid, Change_color, play_file_name, date_played FROM insert_log
WHERE play_file_name NOT IN('Prompt1','Conclusion_Prompt_1','silent')
ORDER BY callid ASC) t1 JOIN (SELECT MAX(date_played) AS date_played FROM insert_log GROUP BY callid) t2 ON t1.date_played=t2.date_played
Ответ 8
rownumber() over (...) работает, но мне не понравилось это решение по двум причинам.
- Эта функция недоступна, если вы используете более старую версию SQL, такую как SQL2000
- Зависимость от функции и на самом деле не читается.
Другое решение:
SELECT tmpall.[OrderNO] ,
tmpall.[PartCode] ,
tmpall.[Quantity] ,
FROM (SELECT [OrderNO],
[PartCode],
[Quantity],
[DateEntered]
FROM you_table) AS tmpall
INNER JOIN (SELECT [OrderNO],
Max([DateEntered]) AS _max_date
FROM your_table
GROUP BY OrderNO ) AS tmplast
ON tmpall.[OrderNO] = tmplast.[OrderNO]
AND tmpall.[DateEntered] = tmplast._max_date