Udostępnij za pośrednictwem


SELECT — klauzula WINDOW (Transact-SQL)

Dotyczy: SQL Server 2022 (16.x) i nowsze wersje bazy danychSQL Sql Azure SQLDatabase wusłudze Microsoft Fabric

Nazwana definicja okna w WINDOW klauzuli określa partycjonowanie i kolejność zestawu wierszy przed funkcją okna, która używa okna w klauzuli OVER .

Klauzula WINDOW wymaga poziomu 160 zgodności bazy danych lub wyższego. Jeśli poziom zgodności bazy danych jest niższy niż 160, aparat bazy danych nie może wykonywać zapytań za pomocą klauzuli WINDOW .

Poziom zgodności można sprawdzić w sys.databases widoku lub we właściwościach bazy danych. Poziom zgodności bazy danych można zmienić za pomocą następującego polecenia:

ALTER DATABASE DatabaseName
SET COMPATIBILITY_LEVEL = 160;

Transact-SQL konwencje składni

Składnia

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>

Argumenty (w programowaniu)

window_name

Nazwa zdefiniowanej specyfikacji okna. Ta nazwa jest używana przez funkcje okna w klauzuli OVER , aby odwoływać się do specyfikacji okna. Nazwy okien muszą być zgodne z regułami dotyczącymi identyfikatorów.

reference_window_name

Nazwa okna, do których odwołuje się bieżące okno. Okno, do których odwołuje się odwołanie, musi znajdować się w oknach zdefiniowanych w klauzuli WINDOW .

Inne argumenty to:

  • PARTITION BY dzielący zestaw wyników zapytania na partycje.

  • ORDER BY definiujące logiczną kolejność wierszy w każdej partycji zestawu wyników.

  • WIERSZE/ZAKRES , które ograniczają wiersze w partycji przez określenie punktów początkowych i końcowych w partycji.

Aby uzyskać bardziej szczegółowe informacje na temat argumentów, zobacz klauzulę OVER

Uwagi

W klauzuli WINDOW można zdefiniować więcej niż jedno nazwane okno.

Więcej składników można dodać do nazwanego okna w OVER klauzuli przy użyciu window_name i dodatkowych specyfikacji. Jednak właściwości określone w WINDOW klauzuli nie można ponownie zdefiniować w klauzuli OVER .

Jeśli zapytanie używa wielu okien, jedno nazwane okno może odwoływać się do innego nazwanego okna przy użyciu window_name. W tym przypadku przywołyną window_name należy określić w definicji okna odwołującego się okna. Składnik okna zdefiniowany w jednym oknie nie może zostać ponownie zdefiniowany przez inne okno odwołujące się do niego.

Na podstawie kolejności, w jakiej okna są zdefiniowane w klauzuli okna, odwołania do okna do przodu i do tyłu są dozwolone. Innymi słowy, okno może używać dowolnego innego okna zdefiniowanego w wyrażeniu okna, którego częścią jest reference_window_name, niezależnie od kolejności, w jakiej są zdefiniowane. Odwołania cykliczne i używanie wielu odwołań do okien w jednym oknie nie jest dozwolone.

Zakres nowego window_name zdefiniowanego okna zawartego w wyrażeniu okna składa się z dowolnych definicji okien, które są częścią wyrażenia okna, wraz z SELECT klauzulą specyfikacji zapytania lub SELECT instrukcji zawierającej klauzulę okna. Jeśli wyrażenie okna jest zawarte w specyfikacji zapytania, która jest częścią wyrażenia zapytania, które jest podstawowym zapytaniem tabeli, zakres nowego window_name zawiera ORDER BY również wyrażenie, jeśli istnieje, tego wyrażenia zapytania.

Ograniczenia dotyczące użycia specyfikacji okien w OVER klauzuli z funkcjami agregowanymi i analitycznymi na podstawie ich semantyki mają zastosowanie do WINDOW klauzuli .

Przykłady

Przykłady kodu w tym artykule korzystają z przykładowej bazy danych AdventureWorks2022 lub AdventureWorksDW2022, którą można pobrać ze strony głównej Przykładów programu Microsoft SQL Server i projektów społeczności.

Odp. Określanie okna zdefiniowanego w klauzuli window

Poniższe przykładowe zapytanie przedstawia użycie nazwanego okna w klauzuli OVER .

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

Poniższe zapytanie jest odpowiednikiem poprzedniego zapytania bez używania klauzuli WINDOW .

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

Oto zestaw wyników.

Numer wiersza Nazwisko SalesYTD Kod pocztowy
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. Określanie pojedynczego okna w wielu klauzulach OVER

W poniższym przykładzie przedstawiono definiowanie specyfikacji okna i wielokrotne używanie jej w klauzuli OVER .

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

Poniższe zapytanie jest odpowiednikiem poprzedniego zapytania bez używania klauzuli WINDOW .

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

Oto zestaw wyników.

ID Zamówienia Sprzedaży IdentyfikatorProduktu IlośćZamówienia Łącznie Średnia Liczba Minuta Maks
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. Definiowanie wspólnej specyfikacji w klauzuli window

W tym przykładzie pokazano definiowanie wspólnej specyfikacji w oknie i używanie jej do definiowania dodatkowych specyfikacji w klauzuli OVER .

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

Poniższe zapytanie jest odpowiednikiem poprzedniego zapytania bez używania klauzuli WINDOW .

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

Oto zestaw wyników.

OrderNumber IdentyfikatorProduktu Ilość Łącznie Średnia Liczba
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. Odwołania do okna do przodu i do tyłu

W tym przykładzie pokazano używanie nazwanych okien jako odwołań do przodu i wstecz podczas definiowania nowego okna w klauzuli WINDOW .

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

Poniższe zapytanie jest odpowiednikiem poprzedniego zapytania bez używania klauzuli WINDOW .

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

Oto zestaw wyników.

OrderNumber IdentyfikatorProduktu Ilość Łącznie Średnia
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