Clausola SELECT - WINDOW (Transact-SQL)
Si applica a: SQL Server 2022 (16.x) Database Azure SQL Istanza gestita di SQL di Azure
La definizione di finestra denominata nella WINDOW
clausola determina il partizionamento e l'ordinamento di un set di righe prima della funzione window, che usa la finestra in una OVER
clausola .
La WINDOW
clausola richiede il livello 160
di compatibilità del database o superiore. Se il livello di compatibilità del database è inferiore a 160
, il motore di database non può eseguire query con la WINDOW
clausola .
È possibile controllare il livello di compatibilità nella sys.databases
vista o nelle proprietà del database. È possibile modificare il livello di compatibilità di un database con il comando seguente:
ALTER DATABASE DatabaseName
SET COMPATIBILITY_LEVEL = 160;
Convenzioni relative alla sintassi Transact-SQL
Sintassi
WINDOW window_name AS (
[ reference_window_name ]
[ <PARTITION BY clause> ]
[ <ORDER BY clause> ]
[ <ROW or RANGE clause> ]
)
<PARTITION BY clause> ::=
PARTITION BY value_expression , ... [ n ]
<ORDER BY clause> ::=
ORDER BY order_by_expression
[ COLLATE collation_name ]
[ ASC | DESC ]
[ , ...n ]
<ROW or RANGE clause> ::=
{ ROWS | RANGE } <window frame extent>
Argomenti
window_name
Nome della specifica della finestra definita. Questo nome viene usato dalle funzioni della finestra nella OVER
clausola per fare riferimento alla specifica della finestra. I nomi di finestra devono essere conformi alle regole per gli identificatori.
reference_window_name
Nome della finestra a cui fa riferimento la finestra corrente. La finestra a cui si fa riferimento deve essere tra le finestre definite nella WINDOW
clausola .
Gli altri argomenti sono:
PARTITION BY, che suddivide il set dei risultati della query in partizioni.
ORDER BY, che definisce l'ordine logico delle righe all'interno di ogni partizione del set di risultati.
ROWS/RANGE, che limita le righe all'interno della partizione specificando i punti iniziali e finali.
Per informazioni più specifiche sugli argomenti, vedere la clausola OVER
Osservazioni:
È possibile definire più finestre denominate nella WINDOW
clausola .
È possibile aggiungere altri componenti a una finestra denominata nella OVER
clausola usando il window_name seguito dalle specifiche aggiuntive. Tuttavia, le proprietà specificate nella WINDOW
clausola non possono essere ridefinite nella OVER
clausola .
Quando una query usa più finestre, una finestra denominata può fare riferimento a un'altra finestra denominata usando il window_name. In questo caso, il window_name a cui viene fatto riferimento deve essere specificato nella definizione della finestra di riferimento. Un componente finestra definito in una finestra non può essere ridefinito facendo riferimento a un'altra finestra.
In base all'ordine in cui le finestre sono definite nella clausola WINDOW, sono consentiti riferimenti in avanti e all'indietro a finestre. In altre parole, una finestra può usare qualsiasi altra finestra definita nell'espressione della finestra di cui fa parte, come reference_window_name, indipendentemente dall'ordine in cui sono definite. I riferimenti ciclici e l'uso di più riferimenti di finestra in una singola finestra non sono consentiti.
L'ambito del nuovo window_name di una finestra definita contenuta in un'espressione di finestra è costituito da tutte le definizioni di finestra che fanno parte dell'espressione finestra, insieme alla SELECT
clausola della specifica SELECT
o dell'istruzione della query che contiene la clausola window. Se l'espressione di finestra è contenuta in una specifica di query che fa parte dell'espressione di query, ovvero una query di tabella di base, l'ambito del nuovo window_name include anche l'espressione ORDER BY
, se presente, di tale espressione di query.
Le restrizioni per l'utilizzo delle specifiche di finestra nella OVER
clausola con le funzioni di aggregazione e analisi in base alla relativa semantica sono applicabili alla WINDOW
clausola .
Esempi
Gli esempi di codice Transact-SQL in questo articolo utilizzano il database campione AdventureWorks2022
o AdventureWorksDW2022
, che è possibile scaricare dalla home page di Esempi di Microsoft SQL Server e progetti collettivi.
R. Specificare una finestra definita nella clausola window
Nella query di esempio seguente viene utilizzata una finestra denominata nella OVER
clausola .
ALTER DATABASE AdventureWorks2022
SET COMPATIBILITY_LEVEL = 160;
GO
USE AdventureWorks2022;
GO
SELECT ROW_NUMBER() OVER win AS [Row Number],
p.LastName,
s.SalesYTD,
a.PostalCode
FROM Sales.SalesPerson AS s
INNER JOIN Person.Person AS p
ON s.BusinessEntityID = p.BusinessEntityID
INNER JOIN Person.Address AS a
ON a.AddressID = p.BusinessEntityID
WHERE TerritoryID IS NOT NULL
AND SalesYTD <> 0
WINDOW win AS
(
PARTITION BY PostalCode ORDER BY SalesYTD DESC
)
ORDER BY PostalCode;
GO
La query seguente è l'equivalente della query precedente senza usare la WINDOW
clausola .
USE AdventureWorks2022;
GO
SELECT ROW_NUMBER() OVER (
PARTITION BY PostalCode ORDER BY SalesYTD DESC
) AS [Row Number],
p.LastName,
s.SalesYTD,
a.PostalCode
FROM Sales.SalesPerson AS s
INNER JOIN Person.Person AS p
ON s.BusinessEntityID = p.BusinessEntityID
INNER JOIN Person.Address AS a
ON a.AddressID = p.BusinessEntityID
WHERE TerritoryID IS NOT NULL
AND SalesYTD <> 0
ORDER BY PostalCode;
GO
Il set di risultati è il seguente.
Numero di riga | LastName | SalesYTD | PostalCode |
---|---|---|---|
1 | Mitchell | 4251368,5497 | 98027 |
2 | Blythe | 3763178,1787 | 98027 |
3 | Carson | 3189418,3662 | 98027 |
4 | Reiter | 2315185,611 | 98027 |
5 | Vargas | 1453719,4653 | 98027 |
6 | Ansman-Wolfe | 1352577,1325 | 98027 |
1 | Pak | 4116871,2277 | 98055 |
2 | Varkey Chudukatil | 3121616,3202 | 98055 |
3 | Saraiva | 2604540,7172 | 98055 |
4 | Ito | 2458535,6169 | 98055 |
5 | Valdez | 1827066,7118 | 98055 |
6 | Mensa-Annan | 1576562,1966 | 98055 |
7 | Campbell | 1573012,9383 | 98055 |
8 | Tsoflias | 1421810,9242 | 98055 |
B. Specificare una singola finestra in più clausole OVER
Nell'esempio seguente viene illustrata la definizione di una specifica di finestra e l'uso più volte in una OVER
clausola .
ALTER DATABASE AdventureWorks2022
SET COMPATIBILITY_LEVEL = 160;
GO
USE AdventureWorks2022;
GO
SELECT SalesOrderID,
ProductID,
OrderQty,
SUM(OrderQty) OVER win AS [Total],
AVG(OrderQty) OVER win AS [Avg],
COUNT(OrderQty) OVER win AS [Count],
MIN(OrderQty) OVER win AS [Min],
MAX(OrderQty) OVER win AS [Max]
FROM Sales.SalesOrderDetail
WHERE SalesOrderID IN (43659, 43664)
WINDOW win AS (PARTITION BY SalesOrderID);
GO
La query seguente è l'equivalente della query precedente senza usare la WINDOW
clausola .
USE AdventureWorks2022;
GO
SELECT SalesOrderID,
ProductID,
OrderQty,
SUM(OrderQty) OVER (PARTITION BY SalesOrderID) AS [Total],
AVG(OrderQty) OVER (PARTITION BY SalesOrderID) AS [Avg],
COUNT(OrderQty) OVER (PARTITION BY SalesOrderID) AS [Count],
MIN(OrderQty) OVER (PARTITION BY SalesOrderID) AS [Min],
MAX(OrderQty) OVER (PARTITION BY SalesOrderID) AS [Max]
FROM Sales.SalesOrderDetail
WHERE SalesOrderID IN (43659, 43664);
GO
Il set di risultati è il seguente.
SalesOrderID | ProductID | OrderQty | Totale | Avg | Count | Min | Max |
---|---|---|---|---|---|---|---|
43659 | 776 | 1 | 26 | 2 | 12 | 1 | 6 |
43659 | 777 | 3 | 26 | 2 | 12 | 1 | 6 |
43659 | 778 | 1 | 26 | 2 | 12 | 1 | 6 |
43659 | 771 | 1 | 26 | 2 | 12 | 1 | 6 |
43659 | 772 | 1 | 26 | 2 | 12 | 1 | 6 |
43659 | 773 | 2 | 26 | 2 | 12 | 1 | 6 |
43659 | 774 | 1 | 26 | 2 | 12 | 1 | 6 |
43659 | 714 | 3 | 26 | 2 | 12 | 1 | 6 |
43659 | 716 | 1 | 26 | 2 | 12 | 1 | 6 |
43659 | 709 | 6 | 26 | 2 | 12 | 1 | 6 |
43659 | 712 | 2 | 26 | 2 | 12 | 1 | 6 |
43659 | 711 | 4 | 26 | 2 | 12 | 1 | 6 |
43664 | 772 | 1 | 14 | 1 | 8 | 1 | 4 |
43664 | 775 | 4 | 14 | 1 | 8 | 1 | 4 |
43664 | 714 | 1 | 14 | 1 | 8 | 1 | 4 |
43664 | 716 | 1 | 14 | 1 | 8 | 1 | 4 |
43664 | 777 | 2 | 14 | 1 | 8 | 1 | 4 |
43664 | 771 | 3 | 14 | 1 | 8 | 1 | 4 |
43664 | 773 | 1 | 14 | 1 | 8 | 1 | 4 |
43664 | 778 | 1 | 14 | 1 | 8 | 1 | 4 |
C. Definire la specifica comune nella clausola window
In questo esempio viene illustrata la definizione di una specifica comune in una finestra e l'uso per definire specifiche aggiuntive nella OVER
clausola .
ALTER DATABASE AdventureWorks2022
SET COMPATIBILITY_LEVEL = 160;
GO
USE AdventureWorks2022;
GO
SELECT SalesOrderID AS OrderNumber,
ProductID,
OrderQty AS Qty,
SUM(OrderQty) OVER win AS Total,
AVG(OrderQty) OVER (win PARTITION BY SalesOrderID) AS Avg,
COUNT(OrderQty) OVER (
win ROWS BETWEEN UNBOUNDED PRECEDING
AND 1 FOLLOWING
) AS Count
FROM Sales.SalesOrderDetail
WHERE SalesOrderID IN (43659, 43664)
AND ProductID LIKE '71%'
WINDOW win AS
(
ORDER BY SalesOrderID, ProductID
);
GO
La query seguente è l'equivalente della query precedente senza usare la WINDOW
clausola .
USE AdventureWorks2022;
GO
SELECT SalesOrderID AS OrderNumber,
ProductID,
OrderQty AS Qty,
SUM(OrderQty) OVER (ORDER BY SalesOrderID, ProductID) AS Total,
AVG(OrderQty) OVER (
PARTITION BY SalesOrderID ORDER BY SalesOrderID, ProductID
) AS Avg,
COUNT(OrderQty) OVER (
ORDER BY SalesOrderID,
ProductID ROWS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING
) AS Count
FROM Sales.SalesOrderDetail
WHERE SalesOrderID IN (43659, 43664)
AND ProductID LIKE '71%';
GO
Il set di risultati è il seguente.
OrderNumber | ProductID | Qtà | Totale | Avg | Count |
---|---|---|---|---|---|
43659 | 711 | 4 | 4 | 4 | 2 |
43659 | 712 | 2 | 6 | 3 | 3 |
43659 | 714 | 3 | 9 | 3 | 4 |
43659 | 716 | 1 | 10 | 2 | 5 |
43664 | 714 | 1 | 11 | 1 | 6 |
43664 | 716 | 1 | 12 | 1 | 6 |
D. Riferimenti in avanti e all'indietro alla finestra
In questo esempio viene illustrato l'uso di finestre denominate come riferimenti avanti e indietro durante la definizione di una nuova finestra nella WINDOW
clausola .
ALTER DATABASE AdventureWorks2022
SET COMPATIBILITY_LEVEL = 160;
GO
USE AdventureWorks2022;
GO
SELECT SalesOrderID AS OrderNumber, ProductID,
OrderQty AS Qty,
SUM(OrderQty) OVER win2 AS Total,
AVG(OrderQty) OVER win1 AS Avg
FROM Sales.SalesOrderDetail
WHERE SalesOrderID IN(43659,43664) AND
ProductID LIKE '71%'
WINDOW win1 AS (win3),
win2 AS (ORDER BY SalesOrderID, ProductID),
win3 AS (win2 PARTITION BY SalesOrderID);
GO
La query seguente è l'equivalente della query precedente senza usare la WINDOW
clausola .
USE AdventureWorks2022;
GO
SELECT SalesOrderID AS OrderNumber, ProductID,
OrderQty AS Qty,
SUM(OrderQty) OVER (ORDER BY SalesOrderID, ProductID) AS Total,
AVG(OrderQty) OVER (PARTITION BY SalesOrderID ORDER BY SalesOrderID, ProductID) AS Avg
FROM Sales.SalesOrderDetail
WHERE SalesOrderID IN(43659,43664) AND
ProductID LIKE '71%';
GO
Il set di risultati è il seguente.
OrderNumber | ProductID | Qtà | Totale | Media |
---|---|---|---|---|
43659 | 711 | 4 | 4 | 4 |
43659 | 712 | 2 | 6 | 3 |
43659 | 714 | 3 | 9 | 3 |
43659 | 716 | 1 | 10 | 2 |
43664 | 714 | 1 | 11 | 1 |
43664 | 716 | 1 | 12 | 1 |