2012-10-17 11 views
16

Powiel możliwe:
How to get the record of a table who contains the maximum value?SQL select max (data) i odpowiednia wartość

Mam łączną zapytanie tak:

SELECT TrainingID, Max(CompletedDate) as CompletedDate, Max(Notes) as Notes  --This will only return the longest notes entry 
FROM HR_EmployeeTrainings ET 
WHERE (ET.AvantiRecID IS NULL OR ET.AvantiRecID = @avantiRecID) 
GROUP BY AvantiRecID, TrainingID    

Która jest działa i zwraca poprawne dane przez większość czasu, ale zauważyłem problem. Zwracane pole z Notatnikiem niekoniecznie musi odpowiadać rekordowi, z którego pochodzi max (completedDate). Zamiast tego będzie to ten z najdłuższym ciągiem? Lub ten, który ma najwyższą wartość ASCII? Co robi program SQL Server w przypadku powiązania między dwoma rekordami? Nie jestem nawet pewien. To, co chcę uzyskać, to pole z uwagami z rekordu max (completedDate). Jak powinienem to zrobić?

+0

Czy CompletedDate nie jest DateTime? – Frobzig

+0

To jest DateTime. Nie ma problemu z tym polem, ale z Notatkami. – MAW74656

+0

maksymalne nuty lub wszystkie nuty dla 'max (completedDate)'? – Marc

Odpowiedz

23

Można użyć podzapytania. Podzapytanie otrzyma numer Max(CompletedDate). Następnie wziąć tę wartość i dołącz na stole ponownie pobrać nuty skojarzyć z tą datą:

select ET1.TrainingID, 
    ET1.CompletedDate, 
    ET1.Notes 
from HR_EmployeeTrainings ET1 
inner join 
(
    select Max(CompletedDate) CompletedDate, TrainingID 
    from HR_EmployeeTrainings 
    --where AvantiRecID IS NULL OR AvantiRecID = @avantiRecID 
    group by TrainingID 
) ET2 
    on ET1.TrainingID = ET2.TrainingID 
    and ET1.CompletedDate = ET2.CompletedDate 
where ET1.AvantiRecID IS NULL OR ET1.AvantiRecID = @avantiRecID 
3

Nie ma łatwy sposób to zrobić, ale coś jak to będzie działać:

SELECT ET.TrainingID, 
    ET.CompletedDate, 
    ET.Notes 
FROM 
HR_EmployeeTrainings ET 
inner join 
(
    select TrainingID, Max(CompletedDate) as CompletedDate 
    FROM HR_EmployeeTrainings 
    WHERE (ET.AvantiRecID IS NULL OR ET.AvantiRecID = @avantiRecID) 
    GROUP BY AvantiRecID, TrainingID 
) ET2 
    on ET.TrainingID = ET2.TrainingID 
    and ET.CompletedDate = ET2.CompletedDate 
+0

Twoja składnia jest niepoprawna dla podkwerendy, brakuje ci klauzuli "OD". – Taryn

3

Każda funkcja MAX jest oceniany indywidualnie. Tak więc MAX (CompletedDate) zwróci wartość ostatniej kolumny CompletedDate, a MAX (Notes) zwróci wartość maksymalną (tj. Najwyższą alfabetycznie).

Musisz inaczej sformatować zapytanie, aby uzyskać to, czego chcesz. To pytanie rzeczywiście już zadawane i odpowiedział na kilka razy, więc nie będę powtarzać go:

How to find the record in a table that contains the maximum value?

Finding the record with maximum value in SQL

+1

Jeśli odpowiedź na to pytanie została już wielokrotnie potwierdzona, prawidłową rzeczą jest głosowanie na zamknięcie jako "dokładny duplikat". – Tony

+0

Thx, właśnie to zrobiłem. – Marplesoft

5

Ach tak, to w jaki sposób jest on przeznaczony w SQL. Otrzymasz maksimum każdej kolumny osobno. Wygląda na to, że chcesz zwrócić wartości z wiersza z maksymalną datą, więc musisz wybrać wiersz z maksymalną datą. Wolę to zrobić z podselekcją, ponieważ zapytania sprawiają, że kompakt jest łatwy do odczytania.

SELECT TrainingID, CompletedDate, Notes 
FROM HR_EmployeeTrainings ET 
WHERE (ET.AvantiRecID IS NULL OR ET.AvantiRecID = @avantiRecID) 
AND CompletedDate in 
    (Select Max(CompletedDate) from HR_EmployeeTrainings B 
    where B.TrainingID = ET.TrainingID) 

Jeśli chcesz również dopasować przez AntiRecID, powinieneś również uwzględnić to w podselekcji.