Quais são as versões do SQL Server 2012 do FIRST () e LAST ()?

10

Eu tenho uma tabela com uma valuecoluna. Quero calcular a última linha menos a primeira linha, como mostrado aqui:

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

Eu quero obter 200 - 10 = 190

No entanto, tentei usar o comando abaixo no SQL Server 2012 LASTe FIRSTnão funciona.

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

Qual é a sintaxe para este comando no SQL Server?

mohammad2050
fonte
@ mohammad2050 - o problema é como você define as linhas "primeira" e "última". Existe alguma outra coluna que define qual deve ser o pedido? Por exemplo, existe uma IDENTITYcoluna ou talvez uma DATETIMEcoluna que define quais são as "primeira" e "última" linhas?
Max Vernon
11
sim, eu tenho coluna id que é de 1 para a última e é coluna de identidade e tanques de Max para editar o meu problema
mohammad2050

Respostas:

20

Você era próximo - FIRSTe LASTé do Access; no SQL Server (começando no SQL Server 2012) eles são FIRST_VALUE()e LAST_VALUE().

Portanto, se você tem 2012 ou melhor (ou Banco de Dados SQL do Azure), aqui está uma maneira de obter sua resposta:

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
fonte
9

Mais uma maneira (que também funciona em versões mais antigas):

SELECT 
    result = (SELECT TOP (1) value FROM counter ORDER BY id DESC)
             - (SELECT TOP (1) value FROM counter ORDER BY id ASC) ;
ypercubeᵀᴹ
fonte
1

Aqui está uma maneira de você fazer isso:

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

A idéia aqui é definir as linhas "primeira" e "última". Depois de defini-los, você pode simplesmente fazer a subtração.

Max Vernon
fonte
-2

Por que não usar as funções MAX e Min (opcional se você tiver Critérios, use Where)

Por exemplo. Selecione (Max (NumFieldName) - Min (NumFieldName)) AS Output FROM TableName

Rupam
fonte
11
Não há garantia de que a Valuecoluna esteja sempre aumentando. A coluna de identidade é, no entanto.
RDFozz