#sql #sql-server-2005 #tsql
#sql #sql-server-2005 #tsql
Вопрос:
Я знаю, что могу сделать это с помощью CTE или другого средства, но мне интересно, можно ли это сделать в одном запросе select (без подвыборок). Я хочу найти самые последние crt_ts для po_nbr, а затем взять соответствующий идентификатор.
Примечание:
Не гарантируется, что столбец id будет последовательным, я упростил его для этого вопроса.
Код:
create table temp
(
id int,
po_nbr int,
crt_ts datetime
)
insert into temp values (20, 100, '09/01/2009')
insert into temp values (3, 100, '09/03/2009')
insert into temp values (5, 100, '09/05/2009')
insert into temp values (6, 100, '09/07/2009')
insert into temp values (4, 200, '08/01/2009')
insert into temp values (29, 200, '08/03/2009')
insert into temp values (12, 200, '08/05/2009')
insert into temp values (18, 200, '08/07/2009')
Желаемый результат:
id po_nbr
---------
6 100
18 200
Комментарии:
1. На самом деле вы не говорите , какими должны быть результаты запроса. Несмотря на это, Томалак, вероятно, прав.
2. Я выдал желаемый результат … результат запроса. обновил вопрос, чтобы прояснить пару вещей.
3. 1 за включение примерной таблицы
Ответ №1:
SELECT
MAX(id) id,
po_nbr
FROM
temp
GROUP BY
po_nbr
Чтобы иметь связанную дату, вы могли бы сделать (осторожно, это подразумевает последовательный идентификатор):
SELECT
temp.id,
temp.po_nbr,
temp.crt_ts
FROM
temp
INNER JOIN (
SELECT MAX(id) id FROM temp GROUP BY po_nbr
) latest ON latest.id = temp.id
Без последовательного идентификатора это было бы:
SELECT
MAX(temp.id) id,
temp.po_nbr,
temp.crt_ts
FROM
temp INNER JOIN (
SELECT MAX(crt_ts) crt_ts, po_nbr
FROM temp i
GROUP BY po_nbr
) latest ON latest.crt_ts = temp.crt_ts AND latest.po_nbr = temp.po_nbr
GROUP BY
temp.po_nbr,
temp.crt_ts
GROUP BY
Можно не указывать, если в po_nbr
группе гарантированно не будет двух одинаковых дат.
Индексы в crt_ts
и po_nbr
справке по последнему запросу, лучше всего создать один комбинированный индекс.
Комментарии:
1. нет гарантии, что столбец ID является последовательным. Мне не обязательно нужен max (id)… Я хочу, чтобы идентификатор, связанный с max (crt_ts), был сгруппирован по po_nbr.
2. использование ROW_NUMBER(), как и в моем ответе, имеет почти половину TotalSubtreeCost в качестве метода GROUP BY (3-я попытка) при использовании SET SHOWPLAN_ALL НА
3. Возможно, но я склонен писать SQL, который также работает на SQL Server 2000, потому что это то, что мы имеем в производстве здесь. :-
Ответ №2:
попробуйте:
SELECT
id,po_nbr --crt_ts --can show the date if you want
FROM (SELECT
id,po_nbr,crt_ts
,ROW_NUMBER() OVER(partition BY po_nbr ORDER BY po_nbr,crt_ts DESC) AS RankValue
FROM temp
) dt
WHERE RankValue=1
Ответ №3:
SELECT
MAX(temp.id) AS id, det.po_nbr
FROM
temp
INNER JOIN (SELECT po_nbr, MAX(crt_ts) AS maxcrt_ts FROM temp GROUP BY po_nbr) AS det ON temp.po_nbr = det.po_nbr AND temp.crt_ts = maxcrt_ts
GROUP BY
det.po_nbr
Ответ №4:
select t.id, tm.po_nbr
from temp t
inner join (
select po_nbr, max(crt_ts) as max_ts
from temp
group by po_nbr
) tm on t.po_nbr = tm.po_nbr and t.crt_ts = max_ts
Ответ №5:
выберите max (id),po_nbr из группы tempbarry по po_nbr