SELECT – WINDOW – (Transact-SQL)
Gilt für: SQL Server 2022 (16.x) Azure SQL-Datenbank Azure SQL verwaltete Instanz
Die benannte Fensterdefinition in der WINDOW-Klausel bestimmt die Partitionierung und Sortierung eines Rowsets, bevor die Fensterfunktion angewendet wird, die das Fenster in der OVER-Klausel verwendet.
Hinweis
Die WINDOW-Klausel benötigt den Datenbank-Kompatibilitätsgrad 160 oder höher. Wenn Ihr Datenbank-Kompatibilitätsgrad niedriger als 160 ist, kann SQL Server keine Abfragen mit der WINDOW-Klausel ausführen.
Sie können den Kompatibilitätsgrad in der Ansicht „sys.databases“ oder in den 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 (Transact-SQL)
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 sich in den in der WINDOW-Klausel definierten Fenstern befinden.
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 Details zu den Argumenten finden Sie unter OVER-Klausel.
Allgemeine Hinweise
In der WINDOW-Klausel können mehrere benannte Fenster definiert werden.
Zusätzliche Komponenten können einem benannten Fenster in der OVER-Klausel hinzugefügt werden, indem der „window_name“ gefolgt von den zusätzlichen Spezifikationen verwendet wird. Die in der WINDOW-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 der referenzierte „window_name“ in der Fensterdefinition des verweisenden 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. Das heißt, dass ein Fenster ein anderes Fenster als reference_window_name
verwenden kann, das in dem <window_expression>
definiert ist, von dem es Teil ist, unabhängig von der Reihenfolge, in der die Fenster definiert sind. Zyklische Verweise und das Verwenden mehrerer Fensterbezüge in einem einzelnen Fenster sind nicht zulässig.
Der Umfang des neuen „window_name“ eines definierten Fensters, das in einer <window_expression>
-Komponente enthalten ist, besteht aus allen Fensterdefinitionen, die Teil des <window_expression>
sind, und der SELECT-Klausel der <query_specification>
oder <SELECT statement>
, die die WINDOW-Klausel enthält. Wenn der <window_expression>
in einer <query_specification>
enthalten ist, die Teil eines <query_expression>
– einer einfachen Tabellenabfrage – ist, umfasst der Umfang des neuen „window_name“, falls vorhanden, auch die <order_by_expression>
des <query_expression>
.
Die Einschränkungen für das Verwenden von Fensterspezifikationen in der OVER-Klausel mit den Aggregat- und Analysefunktionen basierend auf deren Semantik gelten für die WINDOW-Klausel.
Beispiele
A. Angeben eines in der WINDOW-Klausel 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 obigen 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 ist das Resultset.
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 das mehrmalige Verwenden 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 obigen 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 ist das Resultset.
Verkaufsbestellnr | ProductID | OrderQty | Gesamt | 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. Definieren allgemeiner Spezifikationen in der WINDOW-Klausel
In diesem Beispiel wird gezeigt, wie Sie eine allgemeine Spezifikation in einem Fenster definieren und sie zum Definieren zusätzlicher Spezifikationen in der OVER-Klausel verwenden.
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 obigen 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 ist das Resultset.
OrderNumber | ProductID | OrderQty | Gesamt | 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: Vorwärts- und Rückwärtsfensterverweise
In diesem Beispiel wird gezeigt, wie benannte Fenster als Vorwärts- und Rückwärtsverweise verwendet werden, wenn ein neues Fenster in der WINDOW-Klausel definiert wird.
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 obigen 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 ist das Resultset.
OrderNumber | ProductID | OrderQty | 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 |
Siehe auch
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Tickets als Feedbackmechanismus für Inhalte auslaufen lassen und es durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unter:Einreichen und Feedback anzeigen für