Группировка запроса при предоставлении дополнительных выделений


У меня есть следующий запрос

select t1.file_name, 
       max(create_date), 
       t1.id 
 from dbo.translation_style_sheet AS t1 
GROUP BY t1.file_name

Я хотел бы добавить идентификатор в select, но каждый раз, когда я это делаю, он возвращает все результаты, а не мои сгруппированные результаты

Моя цель-вернуться

pdf | 10/1/2012 | 3
doc | 10/2/2012 | 5

Однако мой запрос возвращает

pdf | 9/30/2012 | 1
pdf | 9/31/2012 | 2
pdf | 10/1/2012 | 3
doc | 10/1/2012 | 4
doc | 10/2/2012 | 5
Кто-нибудь знает, что я делаю не так?
2   3   2012-10-27 00:11:03

2 ответа:

Если вы уверены, что строка с max(create_date) также имеет наибольшее значение id (Ваши примерные данные имеют, но я не знаю, является ли это артефактом), вы можете просто выбрать max(id)

select t1.file_name, max(create_date), max(t1.id) 
  from dbo.translation_style_sheet AS t1 
 GROUP BY t1.file_name

Если вы не уверены в этом, и вы хотите, чтобы значение id из строки, которая имеет max(create_date), чтобы быть возвращенным, вы можете использовать аналитические функции. Следующее будет работать в Oracle, хотя маловероятно, что менее сложные базы данных, такие как Derby, будут поддерживать его.

select t1.file_name, t1.create_date, t1.id
  from (select t2.file_name,
               t2.create_date,
               t2.id,
               rank() over (partition by t2.file_name 
                                order by t2.create_date desc) rnk
          from dbo.translation_style_sheet t2) t1 
  where rnk = 1

Ты также можно использовать подзапрос. Это, вероятно, будет более портативным, но менее эффективным, чем подход аналитической функции

select t1.file_name, t1.create_date, t1.id
  from dbo.translation_style_sheet t1
 where (t1.file_name, t1.create_date) in (select t2.file_name, max(t2.create_date)
                                            from dbo.translation_style_sheet t2
                                           group by t2.file_name);

Или

select t1.file_name, t1.create_date, t1.id
  from dbo.translation_style_sheet t1
 where t1.create_date = (select max(t2.create_date) 
                           from dbo.translation_style_sheet t2
                          where t1.file_name = t2.file_name);

При использовании функции GROUP BY необходимо включить в группу все поля, которые не используются агрегатной функцией.

select t1.file_name, max(create_date), t1.id from 
dbo.translation_style_sheet AS t1 GROUP BY t1.file_name, t1.id