Jakie są wersje FIRST () i LAST () w SQL Server 2012?

10

Mam stolik z valuekolumną. Chcę obliczyć ostatni rząd minus pierwszy rząd, jak pokazano tutaj:

 id      value
  1       10
  2       45
  3       65
  4       95
  .       .
  .       .
  .       .
 500     200

Chcę uzyskać 200 - 10 = 190

Próbowałem jednak użyć poniższego polecenia w programie SQL Server 2012 LASTi FIRSTnie działają.

SELECT LAST(Value) - FIRST(Value) FROM Counter;

Jaka jest składnia tego polecenia w SQL Server?

mohammad2050
źródło
@ mohammad2050 - problem polega na tym, jak zdefiniować „pierwszy” i „ostatni” wiersz. Czy jest jakaś inna kolumna, która określa, jaka powinna być kolejność? Na przykład, czy istnieje IDENTITYkolumna, a może DATETIMEkolumna, która określa, jakie są wiersze „pierwszy” i „ostatni”?
Max Vernon,
1
Tak, mam kolumny identyfikator, który wynosi od 1 do ostatniego i jest kolumna tożsamości i zbiorniki Max do edycji mój problem
mohammad2050

Odpowiedzi:

21

Byłeś blisko - FIRSTi LASTjesteś z Access; w SQL Server (począwszy od SQL Server 2012) są FIRST_VALUE()i LAST_VALUE().

Jeśli więc masz rok 2012 lub lepszy (lub Azure SQL Database), oto jeden ze sposobów na uzyskanie odpowiedzi:

CREATE TABLE #fl
(
  IdentityColumn INT IDENTITY, 
  Value INT
);

INSERT #fl(Value) SELECT 10;
INSERT #fl(Value) SELECT 45;
INSERT #fl(Value) SELECT 65;
INSERT #fl(Value) SELECT 95;
INSERT #fl(Value) SELECT 200;

SELECT TOP (1) LAST_VALUE(Value) OVER (ORDER BY IdentityColumn)
            - FIRST_VALUE(Value) OVER (ORDER BY IdentityColumn)
  FROM #fl
  ORDER BY IdentityColumn DESC;

GO
DROP TABLE #fl;
Aaron Bertrand
źródło
9

Jeszcze jeden sposób (który działa również w starszych wersjach):

SELECT 
    result = (SELECT TOP (1) value FROM counter ORDER BY id DESC)
             - (SELECT TOP (1) value FROM counter ORDER BY id ASC) ;
ypercubeᵀᴹ
źródło
1

Oto jeden ze sposobów, w jaki możesz to zrobić:

USE tempdb;

CREATE TABLE dbo.Test1
(
    ID INT NOT NULL
        CONSTRAINT PK_Test1 
        PRIMARY KEY CLUSTERED
        IDENTITY(1,1)
    , Val INT NOT NULL
);
INSERT INTO dbo.Test1 (Val)
VALUES (1)
    , (2)
    , (3)
    , (50);

;WITH FirstAndLast
AS (
    SELECT t.ID
        , t.Val
        , RN  = ROW_NUMBER() OVER (ORDER BY ID)
        , RND = ROW_NUMBER() OVER (ORDER BY ID DESC)
    FROM dbo.Test1 t
)
SELECT TOP(1) l.Val - f.val
FROM FirstAndLast f
    INNER JOIN FirstAndLast l ON f.RN = l.RND

Chodzi tutaj o zdefiniowanie „pierwszego” i „ostatniego” wiersza. Po ich zdefiniowaniu możesz po prostu wykonać odejmowanie.

Max Vernon
źródło
-2

Dlaczego nie użyć funkcji MAX i MIN (opcjonalnie, jeśli masz Kryteria użyj Gdzie)

Na przykład. Wybierz (Max (NumFieldName) - Min (NumFieldName)) AS Output FROM TableName

Rupam
źródło
1
Nie ma gwarancji, że Valuekolumna zawsze rośnie. Jednak kolumna tożsamości to.
RDFozz