Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > MS SQL Server > Выборка значения с максимальной датой


Автор: Cashey 18.8.2015, 20:11
Условие:
Есть таблица, имеет, допустим, три поля:
1. kod - неуникальный идентификатор
2. reason - некое значение
3. dstop - дата, связанная с основным значением
пример:
          kod                            reason          dstop
5068070838000124                1             2013-01-01
5068070838000124                5             2014-02-02
5068070838000124                3             2015-03-03

требуется вытащить только значение поля reason из строки с максимальным значением поля dstop

Я родил такую конструкцию:
Код
SELECT t2.[reason] 
      ,t2.kod 
      ,t2.dstop 
  FROM [REGISTR].[dbo].[S_file] 
  left join (select max(dstop) as ds, kod from [REGISTR].[dbo].[S_file] group by kod)  t1 on S_file.kod = t1.kod
   left join [REGISTR].[dbo].[S_file] t2 on t2.kod = t1.kod and t2.dstop = t1.ds
   where S_file.kod ='5068070838000124' group by t2.[reason], t2.kod, t2.dstop 


Функционально работает, но выглядет как извращение. Задача тривиальная, думаю кому-то уже хватило мозгов создать что-то более рациональное. Спасибо за подсказку.

Автор: Akina 19.8.2015, 08:59
Цитата(Cashey @  18.8.2015,  21:11 Найти цитируемый пост)
требуется вытащить только значение поля reason из строки с максимальным значением поля dstop

Код

SELECT TOP 1 reason
FROM [REGISTR].[dbo].[S_file]
WHERE kod ='5068070838000124'
ORDER BY dstop DESC

Автор: Cashey 19.8.2015, 19:55
Цитата(Akina @ 19.8.2015,  09:59)
Код

SELECT TOP 1 reason
FROM [REGISTR].[dbo].[S_file]
WHERE kod ='5068070838000124'
ORDER BY dstop DESC

Элегантно, но не применимо. Приведенный в примере where S_file.kod ='5068070838000124' лишь частный случай. В общем случае в этом месте предполагается множество. И конструкция может быть where S_file.kod in (...). В этом случае SELECT TOP 1 не работоспособно.

Автор: Akina 19.8.2015, 20:58
Cashey,  значит, сперва обдумайте свой вопрос полностью, а потом спрашивайте.

Автор: ТоляМБА 19.8.2015, 21:02
Код
select S.kod, S.reason, S.dstop
from S_file as S
inner join (
select kod, max(dstop) as A
from S_file
group by kod) as B
on S.kod = B.kod and S.dstop = B.A
where S.kod in ('5068070838000124', '5068070838000125')
order by 1

Автор: Akina 20.8.2015, 09:22
ТоляМБА, я бы рекомендовал фильтр по коду убрать в подзапрос.

Cashey, если версия сервера знает про оконные функции - лучше используй DENSE_RANK() OVER (PARTITION BY kod ORDER BY dstop DESC)

Автор: ТоляМБА 20.8.2015, 10:16
Akina, согласен.

Код
select S.kod, S.reason, S.dstop
from S_file as S
inner join (
select kod, max(dstop) as A
from S_file
where kod in ('5068070838000124', '5068070838000125')
group by kod) as B
on S.kod = B.kod and S.dstop = B.A
order by 1

Автор: Cashey 20.8.2015, 19:12
Цитата(ТоляМБА @ 19.8.2015,  22:02)
Код
select S.kod, S.reason, S.dstop
from S_file as S
inner join (
select kod, max(dstop) as A
from S_file
group by kod) as B
on S.kod = B.kod and S.dstop = B.A
where S.kod in ('5068070838000124', '5068070838000125')
order by 1

Глупо как, я не догодался в выражение ON первого JOIN вставить второе условие, тянув для этого второй JOIN. Но в целом идея та же.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)