2013-05-14 10 views
23

Próbuję uzyskać ostatni rekord datetime z tabeli, która zachowuje wiele status. Moja tabela wygląda tak:SQL uzyskać rekord czasu ostatniej dacie

+---------+------------------------+-------+ 
|filename |Dates     |Status | 
+---------+------------------------+-------+ 
|abc.txt |2012-02-14 12:04:45.397 |Open | 
|abc.txt |2012-02-14 12:14:20.997 |Closed | 
|abc.txt |2013-02-14 12:20:59.407 |Open | 
|dfg.txt |2012-02-14 12:14:20.997 |Closed | 
|dfg.txt |2013-02-14 12:20:59.407 |Open | 
+---------+------------------------+-------+ 

Wyniki powinny być

+---------+------------------------+-------+ 
|filename |Dates     |Status | 
+---------+------------------------+-------+ 
|abc.txt |2013-02-14 12:20:59.407 |Open | 
|dfg.txt |2013-02-14 12:20:59.407 |Open | 
+---------+------------------------+-------+ 
+6

co RDBMS używasz? – wootscootinboogie

Odpowiedz

22

Jeśli chcesz jeden wiersz dla każdego pliku, odzwierciedlając konkretne stany i podając najnowszą datę, to jest twój przyjaciel:

select filename , 
     status , 
     max_date = max(dates) 
from some_table t 
group by filename , status 
having status = '<your-desired-status-here>' 

Łatwy!

+0

Jakieś uwagi na temat wydajności? Powiedz, że ma wiele milionów zapisów, czy istnieje zoptymalizowany sposób robienia tego, czy powinien rozważyć umieszczenie go w nowej tabeli z najnowszymi rekordami? – JPK

+0

Wszystko zależy od indeksów na stole. Musisz sprawdzić plan wykonania. Zgodnie z ogólną zasadą: nie optymalizuj, dopóki nie wystąpi problem. Można wstawić do tabeli wyzwalacz wstawiania/aktualizacji/usunięcia, który zachowałby tabelę podsumowania z najnowszą datą dla każdej kombinacji pliku/statusu. Ma to jednak wpływ na wydajność: każda operacja wstawiania/aktualizacji/usuwania w tabeli szczegółów musi zmodyfikować tabelę podsumowań. Zwiększa także rywalizację w DB (ponieważ blokujesz teraz dwie tabele zamiast jednej). Oznacza to również, że masz teraz dwa źródła prawdy w bazie danych. –

23
SELECT * FROM table 
WHERE Dates IN (SELECT max(Dates) FROM table); 
+0

W jaki sposób uwzględnia się wiele statusów części pytania? – wootscootinboogie

+0

Nie, dostaje wszystkie wpisy pasujące do daty maksymalnej. – vidit

+0

Oto wersja demonstracyjna - http://sqlfiddle.com/#!3/c94a2/1 – Taryn

1

Dokładna składnia będzie oczywiście zależeć od bazy, ale coś takiego:

SELECT * FROM my_table WHERE (filename, Dates) IN (SELECT filename, Max(Dates) FROM my_table GROUP BY filename) 

To da ci wynik Dokładnie to, o co prosisz i wyświetlasz powyżej. Fiddle: http://www.sqlfiddle.com/#!2/3af8a/1/0

9
SELECT TOP 1 * FROM foo ORDER BY Dates DESC 

Powoduje zwrócenie jednego wyniku z najnowszą datą.

SELECT * FROM foo WHERE foo.Dates = (SELECT MAX(Dates) FROM foo) 

Powoduje zwrócenie wszystkich wyników, które mają tę samą maksymalną datę, do milisekundy.

To jest dla SQL Server. Zostawię to do użycia funkcji DATEPART, jeśli chcesz używać dat, ale nie czasów.

2

Zważywszy, że Max (daty) może być różny dla każdego pliku, moje rozwiązanie:

select filename, dates, status 
from yt a 
where a.dates = (
    select max(dates) 
    from yt b 
    where a.filename = b.filename 
) 
; 

http://sqlfiddle.com/#!3/c94a2/2

HTH

-2

Spróbuj tego:

SELECT filename,Dates,Status 
FROM TableName 
WHERE Dates In (SELECT MAX(Dates) FROM TableName GROUP BY filename) 
+0

Może to zwrócić dodatkowe stare daty dla niektórych nazw plików. – Vadzim

+0

Jak, proszę wyjaśnić. – wara

2

to działa

SELECT distinct filename 
,last_value(dates)over (PARTITION BY filename ORDER BY filename)posd 
,last_value(status)over (PARTITION BY filename ORDER BY filename)poss 
FROM distemp.dbo.Shmy_table 
+0

Ta funkcja jest niesamowita, możesz tworzyć pętle rekursywne, aby wypełnić puste dane. –

+0

Od wersji SQL Server 2012: https://docs.microsoft.com/en-us/sql/t-sql/functions/first-value-transact-sql – Vadzim

Powiązane problemy