SELECT - Klausa WINDOW (Transact-SQL)
Berlaku untuk: SQL Server 2022 (16.x) Azure SQL Database Azure SQL Managed Instance
Definisi jendela bernama dalam WINDOW
klausul menentukan pemartisian dan pengurutan set baris sebelum fungsi jendela, yang menggunakan jendela dalam OVER
klausa.
Klausa WINDOW
memerlukan tingkat 160
kompatibilitas database atau lebih tinggi. Jika tingkat kompatibilitas database Anda lebih rendah dari 160
, Mesin Database tidak dapat menjalankan kueri dengan WINDOW
klausa.
Anda dapat memeriksa tingkat kompatibilitas dalam sys.databases
tampilan atau di properti database. Anda bisa mengubah tingkat kompatibilitas database dengan perintah berikut:
ALTER DATABASE DatabaseName
SET COMPATIBILITY_LEVEL = 160;
Sintaks
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>
Argumen
window_name
Nama spesifikasi jendela yang ditentukan. Nama ini digunakan oleh fungsi jendela dalam OVER
klausul untuk merujuk ke spesifikasi jendela. Nama jendela harus mengikuti aturan untuk pengidentifikasi.
reference_window_name
Nama jendela yang sedang dirujuk oleh jendela saat ini. Jendela yang dirujuk harus berada di antara jendela yang ditentukan dalam WINDOW
klausa.
Argumen lainnya adalah:
PARTITION BY yang membagi hasil kueri yang diatur menjadi partisi.
ORDER BY yang menentukan urutan logis baris dalam setiap partisi tataan hasil.
ROWS/RANGE yang membatasi baris dalam partisi dengan menentukan titik awal dan akhir dalam partisi.
Untuk detail lebih spesifik tentang argumen, lihat klausa OVER
Keterangan
Lebih dari satu jendela bernama dapat didefinisikan dalam WINDOW
klausa.
Lebih banyak komponen dapat ditambahkan ke jendela bernama dalam OVER
klausa dengan menggunakan window_name diikuti dengan spesifikasi tambahan. Namun, properti yang ditentukan dalam WINDOW
klausul tidak dapat ditentukan ulang dalam OVER
klausul.
Saat kueri menggunakan beberapa jendela, satu jendela bernama dapat mereferensikan jendela bernama lainnya menggunakan window_name. Dalam hal ini, window_name yang dirujuk harus ditentukan dalam definisi jendela jendela referensi. Komponen jendela yang ditentukan dalam satu jendela tidak dapat ditentukan ulang oleh jendela lain yang mereferensikannya.
Berdasarkan urutan di mana jendela didefinisikan dalam klausa jendela, referensi jendela maju dan mundur diizinkan. Dengan kata lain, jendela mungkin menggunakan jendela lain yang ditentukan dalam ekspresi jendela yang merupakan bagian dari, seperti reference_window_name, terlepas dari urutan pendefinisiannya. Referensi siklik dan menggunakan beberapa referensi jendela dalam satu jendela tidak diizinkan.
Cakupan window_name baru jendela yang ditentukan yang terkandung dalam ekspresi jendela, terdiri dari definisi jendela apa pun yang merupakan bagian dari ekspresi jendela, bersama dengan SELECT
klausul spesifikasi atau SELECT
pernyataan kueri yang berisi klausa jendela. Jika ekspresi jendela terkandung dalam spesifikasi kueri yang merupakan bagian dari ekspresi kueri, yang merupakan kueri tabel dasar, maka cakupan window_name baru juga menyertakan ekspresi, jika ada, dari ekspresi kueri tersebutORDER BY
.
Pembatasan penggunaan spesifikasi jendela dalam OVER
klausul dengan fungsi agregat dan analitik berdasarkan semantiknya berlaku untuk WINDOW
klausul.
Contoh
Sampel kode Transact-SQL dalam artikel ini menggunakan AdventureWorks2022
database sampel atau AdventureWorksDW2022
, yang dapat Anda unduh dari halaman beranda Sampel Microsoft SQL Server dan Proyek Komunitas.
J. Tentukan jendela yang ditentukan dalam klausa jendela
Contoh kueri berikut ini memperlihatkan menggunakan jendela bernama dalam OVER
klausa.
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
Kueri berikut setara dengan kueri sebelumnya tanpa menggunakan WINDOW
klausa.
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
Berikut set hasilnya.
Nomor Baris | 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. Tentukan satu jendela dalam beberapa klausa OVER
Contoh berikut menunjukkan menentukan spesifikasi jendela dan menggunakannya beberapa kali dalam klausa 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
Kueri berikut setara dengan kueri sebelumnya tanpa menggunakan WINDOW
klausa.
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
Berikut set hasilnya.
SalesOrderID | ProductID | OrderQty | Total | Avg | Hitung | Min | 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. Tentukan spesifikasi umum dalam klausa jendela
Contoh ini menunjukkan mendefinisikan spesifikasi umum di jendela dan menggunakannya untuk menentukan spesifikasi tambahan dalam OVER
klausa.
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
Kueri berikut setara dengan kueri sebelumnya tanpa menggunakan WINDOW
klausa.
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
Berikut set hasilnya.
OrderNumber | ProductID | Jml | Total | Avg | Hitung |
---|---|---|---|---|---|
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. Referensi jendela maju dan mundur
Contoh ini menunjukkan penggunaan jendela bernama sebagai referensi maju dan mundur saat menentukan jendela baru dalam WINDOW
klausa.
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
Kueri berikut setara dengan kueri sebelumnya tanpa menggunakan WINDOW
klausa.
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
Berikut set hasilnya.
OrderNumber | ProductID | Jml | 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 |