SELECT - WINDOW-Klausel (Transact-SQL)
Gilt für: SQL Server 2022 (16.x) Azure SQL-Datenbank Azure SQL Managed Instance
Die benannte Fensterdefinition in der WINDOW
Klausel bestimmt die Partitionierung und Sortierung eines Rowsets vor der Fensterfunktion, die das Fenster in einer OVER
Klausel verwendet.
Für die WINDOW
Klausel ist eine Datenbankkompatibilitätsstufe 160
oder höher erforderlich. Wenn die Kompatibilitätsebene der Datenbank niedriger ist als160
, kann die Datenbank-Engine keine Abfragen mit der WINDOW
Klausel ausführen.
Sie können die Kompatibilitätsebene in der sys.databases
Ansicht oder in Datenbankeigenschaften überprüfen. Sie können den Kompatibilitätsgrad einer Datenbank mithilfe des folgenden Befehls ändern:
ALTER DATABASE DatabaseName
SET COMPATIBILITY_LEVEL = 160;
Transact-SQL-Syntaxkonventionen
Syntax
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>
Argumente
window_name
Name der definierten Fensterspezifikation. Dieser Name wird von den Fensterfunktionen in der OVER
Klausel verwendet, um auf die Fensterspezifikation zu verweisen. Fensternamen müssen den Regeln für Bezeichner entsprechen.
reference_window_name
Name des Fensters, auf das durch das aktuelle Fenster verwiesen wird. Das fenster, auf das verwiesen wird, muss zwischen den fenstern stehen, die in der WINDOW
Klausel definiert sind.
Bei den anderen Argumenten handelt es sich um:
PARTITION BY, das das Abfrageresultset in Partitionen unterteilt.
ORDER BY, das die logische Reihenfolge der Zeilen innerhalb jeder Partition des Resultsets definiert.
ROWS/RANGE, das die Zeilen innerhalb der Partition weiter eingrenzt, indem Start- und Endpunkte innerhalb der Partition angegeben werden.
Ausführlichere Informationen zu den Argumenten finden Sie in der OVER-Klausel.
Hinweise
Mehrere benannte Fenster können in der WINDOW
Klausel definiert werden.
Weitere Komponenten können einem benannten Fenster in der OVER
Klausel mithilfe der window_name gefolgt von den zusätzlichen Spezifikationen hinzugefügt werden. Die in WINDOW
der Klausel angegebenen Eigenschaften können jedoch nicht in der OVER
Klausel neu definiert werden.
Wenn eine Abfrage mehrere Fenster verwendet, kann ein benanntes Fenster mithilfe des window_name auf ein anderes benanntes Fenster verweisen. In diesem Fall muss die referenzierte window_name in der Fensterdefinition des referenzierenden Fensters angegeben werden. Eine in einem Fenster definierte Fensterkomponente kann nicht durch ein anderes Fenster neu definiert werden, das darauf verweist.
Basierend auf der Reihenfolge, in der die Fenster in der WINDOW-Klausel definiert sind, sind Vorwärts- und Rückwärtsbezüge für Fenster zulässig. Mit anderen Worten, ein Fenster kann jedes andere Fenster verwenden, das im Fensterausdruck definiert ist, von dem es gehört, als reference_window_name, unabhängig von der Reihenfolge, in der sie definiert sind. Zyklische Bezüge und die Verwendung mehrerer Fensterverweise in einem einzelnen Fenster sind nicht zulässig.
Der Bereich des neuen window_name eines definierten Fensters, das in einem Fensterausdruck enthalten ist, besteht aus allen Fensterdefinitionen, die Teil des Fensterausdrucks sind, zusammen mit der SELECT
Klausel der Abfragespezifikation oder SELECT
-anweisung, die die Fensterklausel enthält. Wenn der Fensterausdruck in einer Abfragespezifikation enthalten ist, die Teil des Abfrageausdrucks ist, bei dem es sich um eine einfache Tabellenabfrage handelt, enthält der Bereich des neuen window_name auch den ORDER BY
Ausdruck (sofern vorhanden) dieses Abfrageausdrucks.
Die Einschränkungen für die Verwendung von Fensterspezifikationen in der OVER
Klausel mit den Aggregat- und Analysefunktionen basierend auf ihrer Semantik gelten für WINDOW
Klauseln.
Beispiele
Die Transact-SQL-Codebeispiele in diesem Artikel verwenden die AdventureWorks2022
- oder AdventureWorksDW2022
-Beispieldatenbank, die Sie von der Homepage Microsoft SQL Server Samples and Community Projects herunterladen können.
A. Angeben eines in der Fensterklausel definierten Fensters
In der folgenden Beispielabfrage wird ein benanntes Fenster in der OVER
Klausel verwendet.
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
Die folgende Abfrage entspricht der vorherigen Abfrage, ohne die WINDOW
Klausel zu verwenden.
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
Hier sehen Sie das Ergebnis.
Row Number | Nachname | 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. Angeben eines einzelnen Fensters in mehreren OVER-Klauseln
Das folgende Beispiel zeigt das Definieren einer Fensterspezifikation und die Mehrfachverwendung in einer OVER
Klausel.
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
Die folgende Abfrage entspricht der vorherigen Abfrage, ohne die WINDOW
Klausel zu verwenden.
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
Hier sehen Sie das Ergebnis.
Verkaufsbestellnr | ProductID | OrderQty | Gesamt | Avg | Anzahl | 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. Definieren der allgemeinen Spezifikation in der Fensterklausel
Dieses Beispiel zeigt das Definieren einer allgemeinen Spezifikation in einem Fenster und die Verwendung, um zusätzliche Spezifikationen in der OVER
Klausel zu definieren.
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
Die folgende Abfrage entspricht der vorherigen Abfrage, ohne die WINDOW
Klausel zu verwenden.
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
Hier sehen Sie das Ergebnis.
OrderNumber | ProductID | Menge | Gesamt | Avg | Anzahl |
---|---|---|---|---|---|
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: Vorwärts- und Rückwärtsfensterverweise
Dieses Beispiel zeigt die Verwendung benannter Fenster als Vorwärts- und Rückwärtsverweise beim Definieren eines neuen Fensters in der WINDOW
Klausel.
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
Die folgende Abfrage entspricht der vorherigen Abfrage, ohne die WINDOW
Klausel zu verwenden.
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
Hier sehen Sie das Ergebnis.
OrderNumber | ProductID | Menge | Gesamt | Avg |
---|---|---|---|---|
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 |