SELECT – WINDOW – (Transact-SQL)

Gilt für: SQL Server 2022 (16.x) Azure SQL-DatenbankAzure SQL Managed Instance

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