2013-06-24 2 views
1

К сожалению, мои знания, связанные с заявлениями типа group by и having весьма ограничен, так что надеюсь, вы можете мне помочь:SQL Server: как получить самую новую дату в таблицу с несколькими одинаковыми клавишами

У меня есть мнение - вот выдержка - (если у нас есть несколько европейцев здесь - это v021 из Winline/мезонного):

ID  | Artikelbezeichnung1     | Bez2  | mesoyear 
_____________________________________________________________________ 
1401MA70 | Marga ,Saracena grigio,1S,33,3/33,3 | Marazzi | 1344 
1401MA70 | Marga ,Saracena grigio,1S,33,3/33,3 | Marazzi | 1356 
1401MA70 | Marga ,Saracena grigio,1S,33,3/33,3 | Marazzi | 1356 
1401MA71 | Marga ,Saracena beige,1S,33,3/33,3 | Marazzi | 1344 
1401MA71 | Marga ,Saracena beige,1S,33,3/33,3 | Marazzi | 1356 
1401MA71 | Marga ,Saracena beige,1S,33,3/33,3 | Marazzi | 1356  
2401CR13 | Crista,Mahon rojo,1S,33,3/33,3  | Cristacer | 1332  
2401CR13 | Crista,Mahon rojo,1S,33,3/33,3  | Cristacer | 1344 

Так ID не является уникальным и мне просто нужно один с самым высоким Валом в mesoyear.

Мой кулак раствор:

Select 
    c015 as ID, 
    c003 as Artikelbezeichnung1, 
    c074 as Bez2, 
    mesoyear 
from 
    CWLDATEN_91.dbo.v021 
group by 
    c015 
having 
    mesoyear = max(mesoyear) 

Но это не работает на всех ...

Msg 8121, Level 16, State 1, Line 8
Колонка «CWLDATEN_91. dbo.v021.mesoyear 'недействителен в предложении HAVING, потому что он не содержится ни в агрегатной функции, ни в предложении GROUP BY.

Так что я просто удалил having заявление и пошел "лучше":

Msg 8120, уровень 16, состояние 1, строка 2
Колонка 'CWLDATEN_91.dbo.v021.c003' является недействителен в списке выбора, потому что он не содержится ни в агрегатной функции, ни в предложении GROUP BY.

Поэтому я попытался удалить ошибку, просто добавив вещи в группу. И это сработало.

Select 
    c015 as ID, 
    c003 as Artikelbezeichnung1, 
    c074 as Bez2, 
    max(mesoyear) 
from 
    CWLDATEN_91.dbo.v021 
group by 
    c015, c003, c074 

дает мне именно то, что я хочу.

Но правильный выбор содержит около 24 столбцов и некоторые вычисления. Проблема не может быть решена только путем добавления всех столбцов в group by ...?

Может кто-нибудь, пожалуйста, помогите мне найти правильную команду?

Спасибо!

+0

Поскольку у вас уже есть ответы, используя 'ROW_NUMBER', я просто собираюсь добавить вам несколько ссылок о ранговых функциях T-SQL - http://msdn.microsoft.com/en-us/library/ms189798.aspx & http://msdn.microsoft.com/en-us/library/ms186734.aspx –

+0

А также, если вы просто хотите использовать 'GROUP BY' - это возможно. Вы можете обернуть результат группировки в подзапрос, затем «JOIN» обратно в исходную таблицу, используя все столбцы группировки. (но я бы рекомендовал row_number) –

ответ

2

Вы действительно не хотите group by. Вы хотите выбрать последнюю строку в каждой группе. Вы можете сделать это с помощью оконной функции называется row_number() (если вы используете SQL Server 2005 или выше):

Select v.* 
from (select v.*, 
      ROW_NUMBER() over (partition by c015, c003, c074 order by mesoyear desc) as seqnum 
     from CWLDATEN_91.dbo.v021 
    ) v 
where seqnum = 1; 

Row_number() присваивает порядковый номер для строк в группе. Таким образом, все строки с одинаковым значением для c015, c003 и c074 (на основе предложения partition by) находятся в группе и нумеруются.Заказы начинаются с самого последнего mesoyear (в соответствии с предложением order by). Таким образом, значение 1 в seqnum является самым последним годом.

1

Вы можете решить эту проблему с ROW_NUMBER() предполагая SQL Server 2005 или более поздней версии

SELECT * 
FROM (SELECT *, ROW_NUMBER() OVER (PARTITION BY c015, c003, c074 ORDER BY mesoyear DESC) RowRank 
     FROM CWLDATEN_91.dbo.v021)sub 
WHERE RowRank = 1 

В ROW_NUMBER() функцию только номера строк, в какой бы способ вы диктовать, здесь это сгруппированы по вашим ключевым полям, и по заказу mesoyear.

+0

Работает отлично! Спасибо !!! – Qohelet