sql >> Databáze >  >> RDS >> Sqlserver

LAST_VALUE v SQL Server 2012 vrací podivné výsledky

SQL Server neví nebo se nezajímá o pořadí, ve kterém byly řádky vloženy do tabulky. Pokud potřebujete konkrétní objednávku, vždy použijte ORDER BY . Ve vašem příkladu ORDER BY je nejednoznačné, pokud nezahrnete PK do ORDER BY . Kromě toho LAST_VALUE funkce může vrátit liché výsledky, pokud si nedáte pozor - viz níže.

Očekávaný výsledek můžete získat pomocí MAX nebo LAST_VALUE (SQLFiddle ). V tomto případě jsou ekvivalentní:

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

Výsledek tohoto dotazu bude stejný bez ohledu na pořadí, ve kterém byly řádky původně vloženy do tabulky. Můžete zkusit vložit INSERT výroky v různém pořadí v houslích. Nemá to vliv na výsledek.

Také LAST_VALUE se nechová úplně tak, jak byste intuitivně očekávali s výchozím oknem (když máte jen ORDER BY v OVER doložka). Výchozí okno je ŘÁDKY MEZI NEOZEŽENÝM PŘEDCHOZÍM A AKTUÁLNÍM ŘÁDKEM , zatímco jste očekávali, že se bude jednat o ŘÁDY MEZI BEZ ODPOVĚDNOSTI PŘEDCHÁZEJÍCÍ A BEZ OMEZENÍ NÁSLEDUJÍCÍ . Zde je odpověď SO s dobré vysvětlení . Odkaz na tuto odpověď SO je na stránce MSDN pro LAST_VALUE . Jakmile je tedy řádkové okno v dotazu explicitně specifikováno, vrátí to, co je potřeba.

Pokud chcete vědět, v jakém pořadí byly řádky vloženy do tabulky, myslím, že nejjednodušším způsobem je použít IDENTITA . Definice vaší tabulky by se tedy změnila na toto:

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

Když INSERT do této tabulky nemusíte zadávat hodnotu pro PK , server by jej vygeneroval automaticky. Zaručuje, že generované hodnoty jsou jedinečné a rostoucí (s kladným parametrem přírůstku), i když do tabulky vkládáte mnoho klientů současně. Mezi vygenerovanými hodnotami mohou být mezery, ale relativní pořadí vygenerovaných hodnot vám řekne, který řádek byl vložen za který řádek.



  1. Pokud odstraním řádek z tabulky v databázi, jak přejmenovat primární klíče

  2. Převedení hexu na obrázek v PHP?

  3. postgres zkrácení je pomalé

  4. Snížení nákladů na hostování databáze:DigitalOcean vs. AWS vs. Azure