Mam tabelę, która ma identyfikator, wartość i datę. W tej tabeli znajduje się wiele identyfikatorów, wartości i dat.
Rekordy są okresowo wstawiane do tej tabeli. Identyfikator zawsze pozostanie taki sam, ale czasami wartość się zmieni.
Jak mogę napisać zapytanie, które da mi identyfikator oraz datę ostatniej zmiany wartości? Uwaga: wartość zawsze wzrośnie.
Z tych przykładowych danych:
Create Table Taco
( Taco_ID int,
Taco_value int,
Taco_date datetime)
Insert INTO Taco
Values (1, 1, '2012-07-01 00:00:01'),
(1, 1, '2012-07-01 00:00:02'),
(1, 1, '2012-07-01 00:00:03'),
(1, 1, '2012-07-01 00:00:04'),
(1, 2, '2012-07-01 00:00:05'),
(1, 2, '2012-07-01 00:00:06'),
(1, 2, '2012-07-01 00:00:07'),
(1, 2, '2012-07-01 00:00:08')
Wynik powinien być:
Taco_ID Taco_date
1 2012-07-01 00:00:05
(Ponieważ 00:05 był ostatnio Taco_Value
zmieniany).
sql-server
sql-server-2008-r2
t-sql
SqlSandwiches
źródło
źródło
taco
że nie ma to nic wspólnego z jedzeniem?Odpowiedzi:
Te dwa zapytania opierają się na założeniu, że
Taco_value
zawsze rośnie w czasie.Alternatywa z mniejszym szaleństwem funkcji okna:
Przykłady w SQLfiddle
Aktualizacja
Dla tych, którzy śledzili, istniała spór o to, co się stanie, jeśli
Taco_value
kiedykolwiek się powtórzy. Jeśli może on przejść z 1 do 2, a następnie z powrotem do 1 dla dowolnegoTaco_ID
, zapytania nie będą działać. Oto rozwiązanie tego przypadku, nawet jeśli nie jest to technika z lukami i wyspami, którą ktoś taki jak Itzik Ben-Gan może wymarzyć, a nawet jeśli nie ma to znaczenia dla scenariusza PO - może to być dotyczy przyszłego czytelnika. Jest trochę bardziej skomplikowany, a także dodałem dodatkową zmienną - takąTaco_ID
, która ma tylko jednąTaco_value
.Jeśli chcesz dołączyć pierwszy wiersz dla dowolnego identyfikatora, w którym wartość w ogóle nie zmieniła się w całym zestawie:
Jeśli chcesz wykluczyć te wiersze, jest to nieco bardziej złożone, ale wciąż niewielkie zmiany:
Zaktualizowano przykłady SQLfiddle
źródło
value
pojawi się ponownie: FiddleZasadniczo jest to sugestia @ Taryn „skondensowana” do pojedynczego SELECT bez tabel pochodnych:
Uwaga: to rozwiązanie uwzględnia postanowienie, które
Taco_value
może tylko wzrosnąć. (Mówiąc dokładniej, zakłada się, żeTaco_value
nie może wrócić do poprzedniej wartości - w rzeczywistości takiej samej jak połączona odpowiedź).Demo SQL Fiddle dla zapytania: http://sqlfiddle.com/#!3/91368/2
źródło
Powinieneś być w stanie korzystać zarówno z funkcji agregujących, jak
min()
imax()
uzyskać wynik:Zobacz SQL Fiddle with Demo
źródło
Jeszcze jedna odpowiedź, która opiera się na założeniu, że wartości nie pojawiają się ponownie (jest to w zasadzie @ zapytanie Aarona 2, skondensowane w jednym mniejszym gnieździe):
Test na: SQL-Fiddle
I odpowiedź na bardziej ogólny problem, w którym wartości mogą się ponownie pojawić:
(lub używając
CROSS APPLY
tak, aby wyświetlić wszystkie powiązane wiersze, w tymvalue
,):Test na: SQL-Fiddle-2
źródło
dbo.Taco UNION ALL SELECT DISTINCT Taco_ID, NULL AS Taco_value, '19000101' AS Taco_date
).FYI +1 za dostarczenie struktury próbki i danych. Jedyne, o co mógłbym prosić, to oczekiwany wynik dla tych danych.
EDYCJA: Ten doprowadzał mnie do szału. Właśnie odkryłem, że istnieje „prosty” sposób, aby to zrobić. Pozbyłem się niewłaściwych rozwiązań i umieściłem takie, które moim zdaniem są poprawne. Oto rozwiązanie podobne do @bluefeets, ale obejmuje testy, które dał @AaronBertrand.
źródło
value
zmiany.Dlaczego nie uzyskać różnicy wartości opóźnienia i wartości wiodącej? jeśli różnica wynosi zero, to się nie zmienia, to nie jest zero, to się zmienia. Można to zrobić za pomocą prostego zapytania:
źródło
lag...
analityczna została wprowadzona dopiero niedawno w SQL Server 2012. Pierwotne pytanie dotyczy rozwiązania SQL Server 2008 R2. Twoje rozwiązanie nie będzie działać dla SQL Server 2008 R2.Czy może to być tak proste jak poniżej?
Biorąc pod uwagę, że taco_value zawsze wzrasta?
ps Sam jestem całkiem początkującym językiem SQL, ale uczę się powoli, ale pewnie.
źródło
Cannot perform an aggregate function on an expression containing an aggregate or a subquery