OVER
句を使用して、行ごとに計算結果を返す関数です。通常の集計関数(SUM、AVG など)とは異なり、結果をグループ化せずに行ごとに保持することができます。
まずないと思うが、サブクエリやビューで使用されている場合やそういったクエリをリファクタリングするときは
ソートや集計でインデックスが機能しなくなってしまったり遅くなったりするうえ実行計画上見つけにくいので
パフォーマンスが求められる時に使用する際はちゃんと実行計画を確認し集計タイミングをミスんないこと。RANK()
SELECT Name, Salary, RANK() OVER (ORDER BY Salary DESC) AS Rank
FROM Employees;
DENSE_RANK()
RANK()
と似ていますが、同順位の後の順位がスキップされません。SELECT Name, Salary, DENSE_RANK() OVER (ORDER BY Salary DESC) AS DenseRank
FROM Employees;
ROW_NUMBER()
SELECT Name, Salary, ROW_NUMBER() OVER (ORDER BY Salary DESC) AS RowNum
FROM Employees;
SUM() OVER()
SELECT Name, Department, Salary,
SUM(Salary) OVER (PARTITION BY Department) AS TotalSalary
FROM Employees;
AVG() OVER()
SELECT Name, Department, Salary,
AVG(Salary) OVER (PARTITION BY Department) AS AvgSalary
FROM Employees;
Employees
テーブルの作成CREATE TABLE Employees (
ID INT PRIMARY KEY,
Name NVARCHAR(50),
Department NVARCHAR(50),
Salary INT
);
Departments
テーブルの作成CREATE TABLE Departments (
DepartmentID INT PRIMARY KEY,
DepartmentName NVARCHAR(50)
);
INSERT INTO Employees VALUES
(1, 'Alice', 'Sales', 5000),
(2, 'Bob', 'Sales', 7000),
(3, 'Charlie', 'HR', 6000),
(4, 'David', 'HR', 6000),
(5, 'Eve', 'IT', 8000);
INSERT INTO Departments VALUES
(1, 'Sales'),
(2, 'HR'),
(3, 'IT');
USE Test_DB; -- 自分のDBの名前に変換
GO
-- 統計情報の取得
SET STATISTICS IO ON;
SET STATISTICS TIME ON;
GO
-- 実行計画の確認 (クエリは実行されない)
SET SHOWPLAN_ALL ON;
GO
SELECT Name, Salary, RANK() OVER (ORDER BY Salary DESC) AS Rank FROM Employees;
GO
SET SHOWPLAN_ALL OFF;
GO