sql >> Database >  >> RDS >> Sqlserver

LAST_VALUE in SQL Server 2012 geeft rare resultaten

SQL Server weet niet of geeft niet om de volgorde waarin rijen in de tabel zijn ingevoegd. Als je een specifieke bestelling nodig hebt, gebruik dan altijd ORDER BY . In jouw voorbeeld ORDER BY is dubbelzinnig, tenzij u PK . opneemt in de ORDER BY . Trouwens, LAST_VALUE functie kan vreemde resultaten opleveren als u niet voorzichtig bent - zie hieronder.

U kunt uw verwachte resultaat krijgen met MAX of LAST_VALUE (SQLFiddle ). In dit geval zijn ze equivalent:

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

Het resultaat van deze query is hetzelfde, ongeacht de volgorde waarin rijen oorspronkelijk in de tabel zijn ingevoegd. Je kunt proberen om INSERT uitspraken in een andere volgorde op de viool. Het heeft geen invloed op het resultaat.

Ook LAST_VALUE gedraagt ​​zich niet helemaal zoals je intuïtief zou verwachten met het standaardvenster (wanneer je gewoon ORDER BY hebt in de OVER clausule). Standaardvenster is ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW , terwijl je had verwacht dat het ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING . Hier is een SO-antwoord met een goede uitleg . De link naar dit SO-antwoord staat op de MSDN-pagina voor LAST_VALUE . Dus, zodra het rijvenster expliciet is gespecificeerd in de query, retourneert het wat nodig is.

Als je de volgorde wilt weten waarin rijen in de tabel zijn ingevoegd, denk ik dat de meest eenvoudige manier is om IDENTITY . De definitie van uw tabel zou dus veranderen in dit:

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

Wanneer u INSERT in deze tabel hoeft u geen waarde op te geven voor PK , zou de server het automatisch genereren. Het garandeert dat gegenereerde waarden uniek en groeiend zijn (met een positieve incrementparameter), zelfs als er veel clients tegelijkertijd in de tabel worden ingevoegd. Er kunnen hiaten zijn tussen de gegenereerde waarden, maar de relatieve volgorde van de gegenereerde waarden zal u vertellen welke rij na welke rij is ingevoegd.



  1. SQL Unieke beperking voor meerdere tabellen

  2. postgresql - booleaanse kolom toevoegen aan tabel, standaard instellen

  3. Hoe schrijf je een SQL-query met parameters om SQL-injectie te voorkomen?

  4. probleem met apex_application_temp_files