Freigeben über


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 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 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 ist das Resultset.

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 ist das Resultset.

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 ist das Resultset.

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