다음을 통해 공유


SELECT - WINDOW 절(Transact-SQL)

적용 대상: SQL Server 2022(16.x) Azure SQL 데이터베이스 Azure SQL Managed Instance

절의 WINDOW 명명된 창 정의는 창 함수 앞에 있는 행 집합의 분할 및 순서를 결정하며, 이는 절의 OVER 창을 사용합니다.

절에는 WINDOW 데이터베이스 호환성 수준 160 이상이 필요합니다. 데이터베이스 호환성 수준이 보다 160낮은 경우 데이터베이스 엔진 절을 사용하여 WINDOW 쿼리를 실행할 수 없습니다.

뷰 또는 데이터베이스 속성에서 sys.databases 호환성 수준을 확인할 수 있습니다. 다음 명령을 사용하여 데이터베이스의 호환성 수준을 변경할 수 있습니다.

ALTER DATABASE DatabaseName
SET COMPATIBILITY_LEVEL = 160;

Transact-SQL 구문 규칙

구문

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>

인수

window_name

정의된 창 사양의 이름입니다. 이 이름은 절의 창 함수에서 OVER 창 사양을 참조하는 데 사용됩니다. 창 이름은 반드시 식별자에 적용되는 규칙을 준수해야 합니다.

reference_window_name

현재 창에서 참조되는 창의 이름입니다. 참조된 창은 절에 WINDOW 정의된 창 중 하나여야 합니다.

다른 인수는 다음과 같습니다.

  • PARTITION BY - 쿼리 결과 집합을 파티션으로 분할합니다.

  • ORDER BY - 결과 집합의 각 파티션 내에서 행의 논리적 순서를 정의합니다.

  • ROWS/RANGE - 파티션 내의 시작점 및 끝점을 지정하여 파티션 내의 행을 제한합니다.

인수에 대한 자세한 내용은 OVER 절을 참조하세요.

설명

절에 둘 이상의 명명된 WINDOW 창을 정의할 수 있습니다.

window_name 추가 사양을 사용하여 절의 OVER 명명된 창에 더 많은 구성 요소를 추가할 수 있습니다. 그러나 절에 WINDOW 지정된 속성은 절에 OVER 다시 정의할 수 없습니다.

쿼리에서 여러 창을 사용하는 경우 명명된 창 하나가 window_name 사용하여 다른 명명된 창을 참조할 수 있습니다. 이 경우 참조되는 window_name 참조 창의 창 정의에 지정해야 합니다. 한 창에 정의된 창 구성 요소는 참조하는 다른 창에서 다시 정의할 수 없습니다.

창 절에서 창이 정의되는 순서에 따라 전향 및 후향 창 참조가 허용됩니다. 즉, 창은 정의된 순서에 관계없이 창 식에 정의된 다른 창을 reference_window_name 사용할 수 있습니다. 순환 참조 및 단일 창에서 여러 창 참조를 사용하는 것은 허용되지 않습니다.

창 식에 포함된 정의된 창의 새 window_name 범위는 창 식의 일부인 모든 창 정의와 창 절이 포함된 쿼리 사양 또는 SELECT 문의 절로 SELECT 구성됩니다. 창 식이 기본 테이블 쿼리인 쿼리 식의 일부인 쿼리 사양에 포함된 경우 새 window_name 범위에 해당 쿼리 식의 식(있는 경우)도 포함됩니다 ORDER BY .

해당 의미 체계를 OVER 기반으로 하는 집계 및 분석 함수를 사용하는 절의 창 사양 사용에 대한 제한 사항은 절에 WINDOW 적용됩니다.

예제

이 문서의 Transact-SQL 코드 샘플은 AdventureWorks2022 또는 AdventureWorksDW2022 샘플 데이터베이스를 사용하며, 이는 Microsoft SQL Server 예시 및 커뮤니티 프로젝트(Microsoft SQL Server Samples and Community Projects) 홈 페이지에서 다운로드할 수 있습니다.

A. 창 절에 정의된 창 지정

다음 예제 쿼리는 절에 명명된 창을 사용하는 방법을 보여 있습니다 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

다음 쿼리는 절을 사용하지 않고 이전 쿼리와 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

결과 집합은 다음과 같습니다.

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. 여러 OVER 절에서 단일 창 지정

다음 예제에서는 창 사양을 정의하고 절에서 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

다음 쿼리는 절을 사용하지 않고 이전 쿼리와 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

결과 집합은 다음과 같습니다.

SalesOrderID ProductID OrderQty 합계 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. 창 절에서 일반 사양 정의

이 예제에서는 창에서 공통 사양을 정의하고 이를 사용하여 절에 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

다음 쿼리는 절을 사용하지 않고 이전 쿼리와 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

결과 집합은 다음과 같습니다.

OrderNumber ProductID 수량 합계 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. 전향 및 후향 창 참조

이 예제에서는 절에서 새 창을 정의할 때 명명된 창을 앞으로 및 뒤로 참조로 사용하는 방법을 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

다음 쿼리는 절을 사용하지 않고 이전 쿼리와 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

결과 집합은 다음과 같습니다.

OrderNumber ProductID 수량 합계 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