Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

LAST_VALUE w SQL Server 2012 zwraca dziwne wyniki

SQL Server nie zna ani nie dba o kolejność wstawiania wierszy do tabeli. Jeśli potrzebujesz konkretnego zamówienia, zawsze użyj ORDER BY . W twoim przykładzie ORDER BY jest niejednoznaczny, chyba że podasz PK do ORDER BY . Poza tym LAST_VALUE funkcja może zwracać nieparzyste wyniki, jeśli nie będziesz ostrożny - patrz poniżej.

Możesz uzyskać oczekiwany wynik za pomocą MAX lub LAST_VALUE (SQLFiddle ). W tym przypadku są one równoważne:

SELECT
    PK, Id1, Id2
    ,MAX(PK) OVER (PARTITION BY Id1, Id2) AS MaxValue
    ,LAST_VALUE(PK) OVER (PARTITION BY Id1, Id2 ORDER BY PK rows between unbounded preceding and unbounded following) AS LastValue
FROM
    Data
ORDER BY id1, id2, PK

Wynik tego zapytania będzie taki sam bez względu na kolejność, w jakiej wiersze zostały pierwotnie wstawione do tabeli. Możesz spróbować wstawić INSERT wypowiedzi w innej kolejności na skrzypcach. Nie wpływa to na wynik.

Ponadto LAST_VALUE zachowuje się niezupełnie tak, jak byś intuicyjnie oczekiwał z domyślnym oknem (kiedy masz po prostu ORDER BY w OVER klauzula). Domyślne okno to WIERSZE MIĘDZY NIEOGRANICZONYM POSTĘPOWANIEM A BIEŻĄCYM WIERSZEM , podczas gdy spodziewałeś się, że będzie to WIERSZE MIĘDZY NIEOGRANICZONYM POSTĘPOWANIEM A NIEOGRANICZONYM NASTĘPNYM . Oto odpowiedź na SO z dobre wyjaśnienie . Link do tej odpowiedzi SO znajduje się na stronie MSDN dla LAST_VALUE . Tak więc, gdy okno wiersza jest wyraźnie określone w zapytaniu, zwraca to, co jest potrzebne.

Jeśli chcesz poznać kolejność wstawiania wierszy do tabeli, myślę, że najprostszym sposobem jest użycie TOŻSAMOŚĆ . Tak więc definicja Twojej tabeli zmieni się na następującą:

CREATE TABLE Data 
(PK INT IDENTITY(1,1) PRIMARY KEY,
Id1 INT,
Id2 INT)

Kiedy WSTAW w tej tabeli nie musisz podawać wartości dla PK , serwer wygeneruje go automatycznie. Gwarantuje to, że generowane wartości są unikalne i rosnące (z dodatnim parametrem przyrostu), nawet jeśli masz wielu klientów jednocześnie wstawiających do tabeli. Mogą występować przerwy między wygenerowanymi wartościami, ale względna kolejność generowanych wartości powie Ci, który wiersz został wstawiony, po którym.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL konwertuje datetime i odejmuje godziny

  2. Utwórz wieloetapowe zadanie agenta SQL Server (T-SQL)

  3. Jak ZMIENIAĆ parametr wartości tabeli?

  4. Tworzenie replikacji pomiędzy SQL Server 2000 (wydawca) a SQL Server 2008 (subskrybent)

  5. Oblicz całkowity koszt monitorowania serwera SQL