sql >> Database teknologi >  >> RDS >> Sqlserver

LAST_VALUE i SQL Server 2012 returnerer mærkelige resultater

SQL Server kender eller bekymrer sig ikke om rækkefølgen, hvori rækkerne blev indsat i tabellen. Hvis du har brug for en bestemt ordre, skal du altid bruge ORDER BY . I dit eksempel ORDER BY er tvetydig, medmindre du inkluderer PK i ORDER BY . Desuden LAST_VALUE funktion kan returnere ulige resultater, hvis du ikke er forsigtig - se nedenfor.

Du kan få dit forventede resultat ved at bruge MAX eller LAST_VALUE (SQLFiddle ). De er ækvivalente i dette tilfælde:

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

Resultatet af denne forespørgsel vil være det samme uanset rækkefølgen, som rækkerne oprindeligt blev indsat i tabellen. Du kan prøve at sætte INSERT udsagn i forskellig rækkefølge i violinen. Det påvirker ikke resultatet.

Også LAST_VALUE opfører sig ikke helt, som du intuitivt ville forvente med standardvinduet (når du kun har ORDER BY i OVER klausul). Standardvinduet er RÆKKER MELLEM UBEGRÆNSET FOREGÅENDE OG AKTUELLE RÆKKE , mens du havde forventet, at det ville være RÆKKER MELLEM UBEGRÆNSET FØLGENDE OG UBEGRÆNSET FØLGENDE . Her er et SO-svar med en god forklaring . Linket til dette SO-svar er på MSDN-siden for LAST_VALUE . Så når rækkevinduet er specificeret eksplicit i forespørgslen, returnerer det det nødvendige.

Hvis du vil vide, i hvilken rækkefølge rækkerne blev indsat i tabellen, tror jeg, den mest enkle måde er at bruge IDENTITET . Så definitionen af ​​din tabel ville ændre sig til dette:

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

Når du INSERT i denne tabel behøver du ikke at angive værdien for PK , vil serveren generere det automatisk. Det garanterer, at genererede værdier er unikke og vokser (med positiv stigningsparameter), selvom du har mange klienter, der indsætter i tabellen på samme tid. Der kan være mellemrum mellem genererede værdier, men den relative rækkefølge af de genererede værdier vil fortælle dig, hvilken række der blev indsat efter hvilken række.



  1. Hvad er fordelene ved VistaDB

  2. SQL JOIN som enkelt række med underordnede værdier som kolonner og mulighed for at ORDER BY underordnet relationsværdi

  3. Brug SqlCommand, hvordan man tilføjer flere parametre til sit objekt, indsættelse via winform i sql-tabel

  4. kunne ikke indlæse biblioteket for oracle_fdw