Quelles sont les versions SQL Server 2012 de FIRST () et LAST ()?

10

J'ai un tableau avec une valuecolonne. Je veux calculer la dernière ligne moins la première ligne, comme indiqué ici:

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

Je veux obtenir 200 - 10 = 190

J'ai cependant essayé d'utiliser la commande ci-dessous dans SQL Server 2012 LASTet FIRSTne fonctionne pas.

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

Quelle est la syntaxe de cette commande dans SQL Server?

mohammad2050
la source
@ mohammad2050 - le problème est de savoir comment définir les "premières" et "dernières" lignes. Y a-t-il une autre colonne qui définit quelle devrait être la commande? Par exemple, existe-t-il une IDENTITYcolonne ou peut-être une DATETIMEcolonne qui définit ce que sont les "premières" et "dernières" lignes?
Max Vernon
1
oui, j'ai la colonne id qui est de 1 pour durer et est la colonne IDENTITY et les réservoirs Max pour éditer mon problème
mohammad2050

Réponses:

20

Vous étiez proche - FIRSTet LASTêtes d'Access; dans SQL Server (à partir de SQL Server 2012), ils sont FIRST_VALUE()et LAST_VALUE().

Donc, si vous êtes 2012 ou mieux (ou Azure SQL Database), voici une façon d'obtenir votre réponse:

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
la source
9

Une autre façon (qui fonctionne également dans les anciennes versions):

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

Voici une façon de procéder:

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

L'idée ici est de définir les "premières" et "dernières" lignes. Une fois que vous les avez définis, vous pouvez simplement faire la soustraction.

Max Vernon
la source
-2

Pourquoi ne pas utiliser les fonctions MAX et Min (facultatif si vous avez des critères, utilisez Où)

Par exemple. Sélectionnez (Max (NumFieldName) - Min (NumFieldName)) AS Output FROM TableName

Rupam
la source
1
Il n'y a aucune garantie que la Valuecolonne augmente toujours. La colonne d'identité l'est cependant.
RDFozz