Cláusula SELECT - WINDOW (Transact-SQL)
Aplica-se a: SQL Server 2022 (16.x) Banco de Dados SQL do Azure Instância Gerenciada de SQL do Azure
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 de janela, que usa a janela em uma OVER
cláusula.
A WINDOW
cláusula requer o nível 160
de compatibilidade do banco de dados ou superior. Se o nível de compatibilidade do banco de dados for inferior a 160
, 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 sys.databases
exibição ou nas propriedades do banco de dados. É possível alterar o nível de compatibilidade de um banco de dados usando o seguinte comando:
ALTER DATABASE DatabaseName
SET COMPATIBILITY_LEVEL = 160;
Convenções de sintaxe de Transact-SQL
Sintaxe
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>
Argumentos
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 de janela 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:
PARTITION BY divide o conjunto de resultados da consulta em partições.
ORDER BY define a ordem lógica das linhas dentro de cada partição do conjunto de resultados.
ROWS/RANGE limita as linhas dentro da partição com a especificação de pontos iniciais e finais na partição.
Para obter detalhes mais específicos sobre os argumentos, consulte a cláusula OVER
Comentários
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. Nesse caso, o window_name referenciado deve ser especificado na definição 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 ele.
Com base na ordem na qual as janelas são definidas na cláusula de janela, as referências de avanço e regressão de janela são permitidas. Em outras palavras, uma janela pode usar qualquer outra janela definida na expressão de janela da qual ela 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 da nova window_name de uma janela definida contida em uma expressão de janela consiste em todas as 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 de janela. 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 do novo 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.
Exemplos
Os exemplos de código do Transact-SQL deste artigo usa o banco de dados de exemplo AdventureWorks2022
ou AdventureWorksDW2022
, que pode ser baixado da home page Microsoft SQL Server Samples and Community Projects.
R. Especificar uma janela definida na cláusula window
A consulta de exemplo 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
Veja a seguir o conjunto de resultados.
Row Number | Sobrenome | 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 a definição de uma especificação de janela e o uso dela 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
Veja a seguir 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
Veja a seguir o conjunto de resultados.
OrderNumber | ProductID | Qtd | 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 avanço e regressão de janela
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
Veja a seguir o conjunto de resultados.
OrderNumber | ProductID | Qtd | 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 |