Delen via


SELECT - WINDOW-component (Transact-SQL)

Van toepassing op: SQL Server 2022 (16.x) en latere versies Van Azure SQL DatabaseAzure SQL Managed InstanceSQL Database in Microsoft Fabric Preview

De benoemde vensterdefinitie in de WINDOW component bepaalt de partitionering en volgorde van een rijenset vóór de vensterfunctie, die het venster in een OVER component gebruikt.

Voor de component is het compatibiliteitsniveau WINDOW van de 160 database of hoger vereist. Als uw databasecompatibiliteitsniveau lager is dan 160, kan de database-engine geen query's uitvoeren met de WINDOW component.

U kunt het compatibiliteitsniveau in de sys.databases weergave of in database-eigenschappen controleren. U kunt het compatibiliteitsniveau van een database wijzigen met de volgende opdracht:

ALTER DATABASE DatabaseName
SET COMPATIBILITY_LEVEL = 160;

Transact-SQL syntaxis-conventies

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>

Arguments

window_name

Naam van de gedefinieerde vensterspecificatie. Deze naam wordt gebruikt door de vensterfuncties in de OVER component om te verwijzen naar de vensterspecificatie. Vensternamen moeten de regels voor id's volgen.

reference_window_name

Naam van het venster waarnaar wordt verwezen door het huidige venster. Het venster waarnaar wordt verwezen, moet een van de vensters zijn die zijn gedefinieerd in de WINDOW component.

De andere argumenten zijn:

  • PARTITION BY waarmee de queryresultatenset wordt verdeeld in partities.

  • ORDER BY die de logische volgorde van de rijen binnen elke partitie van de resultatenset definieert.

  • RIJEN/BEREIK waarmee de rijen binnen de partitie worden beperkt door begin- en eindpunten binnen de partitie op te geven.

Zie de OVER-component voor meer specifieke informatie over de argumenten

Remarks

Er kunnen meer dan één benoemd venster worden gedefinieerd in de WINDOW component.

Meer onderdelen kunnen worden toegevoegd aan een benoemd venster in de OVER component met behulp van de window_name gevolgd door de extra specificaties. De eigenschappen die zijn opgegeven in WINDOW de component, kunnen echter niet opnieuw worden gedefinieerd in de OVER component.

Wanneer een query meerdere vensters gebruikt, kan één benoemd venster verwijzen naar een ander benoemd venster met behulp van de window_name. In dit geval moet de window_name waarnaar wordt verwezen, worden opgegeven in de vensterdefinitie van het venster waarnaar wordt verwezen. Een vensteronderdeel dat in het ene venster is gedefinieerd, kan niet opnieuw worden gedefinieerd door een ander venster waarnaar wordt verwezen.

Op basis van de volgorde waarin de vensters zijn gedefinieerd in de venstercomponent, zijn verwijzingen naar voorwaartse en achterwaartse vensters toegestaan. Met andere woorden, een venster kan elk ander venster gebruiken dat is gedefinieerd in de vensterexpressie waarvan het deel uitmaakt, zoals reference_window_name, ongeacht de volgorde waarin ze zijn gedefinieerd. Cyclische verwijzingen en het gebruik van meerdere vensterverwijzingen in één venster zijn niet toegestaan.

Het bereik van de nieuwe window_name van een gedefinieerd venster in een vensterexpressie bestaat uit vensterdefinities die deel uitmaken van de vensterexpressie, samen met de SELECT component van de queryspecificatie of SELECT -instructie die de venstercomponent bevat. Als de vensterexpressie is opgenomen in een queryspecificatie die deel uitmaakt van de query-expressie, wat een eenvoudige tabelquery is, bevat het bereik van de nieuwe window_name ook de ORDER BY expressie, indien van toepassing, van die query-expressie.

De beperkingen voor het gebruik van vensterspecificaties in de OVER component met de statistische en analytische functies op basis van hun semantiek zijn van toepassing op WINDOW component.

Examples

De codevoorbeelden in dit artikel gebruiken de AdventureWorks2022 of AdventureWorksDW2022 voorbeelddatabase die u kunt downloaden van de startpagina van Microsoft SQL Server Samples en Community Projects .

A. Een venster opgeven dat is gedefinieerd in de venstercomponent

In de volgende voorbeeldquery wordt een benoemd venster in de OVER component gebruikt.

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

De volgende query is het equivalent van de vorige query zonder de WINDOW component te gebruiken.

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 is het resultatenoverzicht.

Row Number 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. Eén venster opgeven in meerdere OVER-componenten

In het volgende voorbeeld ziet u hoe u een vensterspecificatie definieert en deze meerdere keren gebruikt in een OVER component.

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

De volgende query is het equivalent van de vorige query zonder de WINDOW component te gebruiken.

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 is het resultatenoverzicht.

SalesOrderID ProductID OrderQty Total 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. Algemene specificatie definiëren in venstercomponent

In dit voorbeeld ziet u hoe u een algemene specificatie in een venster definieert en deze gebruikt om aanvullende specificaties in de OVER component te definiëren.

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

De volgende query is het equivalent van de vorige query zonder de WINDOW component te gebruiken.

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 is het resultatenoverzicht.

OrderNumber ProductID Qty Total 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. Verwijzingen naar voorwaartse en achterwaartse vensters

In dit voorbeeld ziet u hoe benoemde vensters worden gebruikt als verwijzingen naar voren en achteruit bij het definiëren van een nieuw venster in de WINDOW component.

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

De volgende query is het equivalent van de vorige query zonder de WINDOW component te gebruiken.

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 is het resultatenoverzicht.

OrderNumber ProductID Qty Total 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