Partilhar via


SELECT - Cláusula WINDOW (Transact-SQL)

Aplica-se a: SQL Server 2022 (16.x) e versões posteriores Azure SQL Database AzureSQL Managed InstanceSQL database in Microsoft Fabric

A definição de janela nomeada na WINDOW cláusula determina o particionamento e a ordenação de um conjunto de linhas antes da função window, que usa a janela em uma OVER cláusula.

A WINDOW cláusula requer nível 160 de compatibilidade de banco de dados ou superior. Se o nível de compatibilidade do 160banco de dados for inferior ao , o Mecanismo de Banco de Dados não poderá executar consultas com a WINDOW cláusula.

Você pode verificar o nível de compatibilidade na exibição ou nas propriedades do sys.databases banco de dados. Você pode alterar o nível de compatibilidade de um banco de dados com o seguinte comando:

ALTER DATABASE DatabaseName
SET COMPATIBILITY_LEVEL = 160;

Transact-SQL convenções de sintaxe

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

Nome da especificação da janela definida. Esse nome é usado pelas funções de janela na OVER cláusula para se referir à especificação da janela. Os nomes das janelas devem seguir as regras para identificadores.

reference_window_name

Nome da janela que está sendo referenciada pela janela atual. A janela referenciada deve estar entre as janelas definidas na WINDOW cláusula.

Os outros argumentos são os seguintes:

  • PARTITION BY que divide o conjunto de resultados da consulta em partições.

  • ORDER BY que define a ordem lógica das linhas dentro de cada partição do conjunto de resultados.

  • ROWS/RANGE que limita as linhas dentro da partição, especificando os pontos de início e fim dentro da partição.

Para obter detalhes mais específicos sobre os argumentos, consulte a cláusula OVER

Remarks

Mais de uma janela nomeada pode ser definida na WINDOW cláusula.

Mais componentes podem ser adicionados a uma janela nomeada na OVER cláusula usando o window_name seguido pelas especificações extras. No entanto, as propriedades especificadas na WINDOW cláusula não podem ser redefinidas na OVER cláusula.

Quando uma consulta usa várias janelas, uma janela nomeada pode fazer referência a outra janela nomeada usando o window_name. Neste caso, o window_name referenciado deve ser especificado na definição de janela da janela de referência. Um componente de janela definido em uma janela não pode ser redefinido por outra janela que faça referência a ela.

Com base na ordem em que as janelas são definidas na cláusula window, as referências de janela para frente e para trás são permitidas. Em outras palavras, uma janela pode usar qualquer outra janela definida na expressão de janela da qual faz parte, como reference_window_name, independentemente da ordem em que são definidas. Referências cíclicas e o uso de várias referências de janela em uma única janela não são permitidos.

O escopo do novo window_name de uma janela definida contida em uma expressão de janela, consiste em quaisquer definições de janela que fazem parte da expressão de janela, juntamente com a SELECT cláusula da especificação de consulta ou SELECT instrução que contém a cláusula window. Se a expressão de janela estiver contida em uma especificação de consulta que faz parte da expressão de consulta, que é uma consulta de tabela básica, o escopo da nova window_name também incluirá a ORDER BY expressão, se houver, dessa expressão de consulta.

As restrições para o OVER uso de especificações de janela na cláusula com as funções agregadas e analíticas com base em sua semântica são aplicáveis à WINDOW cláusula.

Examples

Os exemplos de código neste artigo usam o banco de dados de exemplo AdventureWorks2025 ou AdventureWorksDW2025, que pode ser descarregado da página inicial de Exemplos e Projetos da Comunidade do Microsoft SQL Server.

A. Especificar uma janela definida na cláusula window

O exemplo de consulta a seguir mostra que usa uma janela nomeada na OVER cláusula.

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

A consulta a seguir é o equivalente à consulta anterior sem usar a WINDOW cláusula.

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

Aqui está o conjunto de resultados.

Número da linha 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. Especificar uma única janela em várias cláusulas OVER

O exemplo a seguir mostra como definir uma especificação de janela e usá-la várias vezes em uma OVER cláusula.

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

A consulta a seguir é o equivalente à consulta anterior sem usar a WINDOW cláusula.

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

Aqui está o conjunto de resultados.

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. Definir especificação comum na cláusula de janela

Este exemplo mostra a definição de uma especificação comum em uma janela e o uso dela para definir especificações adicionais na OVER cláusula.

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

A consulta a seguir é o equivalente à consulta anterior sem usar a WINDOW cláusula.

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

Aqui está o conjunto de resultados.

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. Referências de janela para frente e para trás

Este exemplo mostra o WINDOW uso de janelas nomeadas como referências para frente e para trás ao definir uma nova janela na cláusula.

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

A consulta a seguir é o equivalente à consulta anterior sem usar a WINDOW cláusula.

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

Aqui está o conjunto de resultados.

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