SQLのrow_number関数についてまとめています。
SQLのrow_number関数の構文
row_number関数は、機能としては「連番を振る」関数です。
SELECT ROW_NUMBER() OVER(ORDER BY score ASC) num , user_name , score FROM scores
【関連記事】
▶SQLで行番号を取得する ROW_NUMBER・ROWNUM・ユーザ定義変数の使い方
しかし、具体的な使い方は、サブクエリと組み合わせることで、グルーピングしたデータの上位n番、下位n番といった条件指定が可能になるんですね。
以下の例は、Cityごとにグルーピングし、scoreを昇順にソートして連番を振っています。
SELECT ROW_NUMBER() OVER(PARTITION BY City ORDER BY Age ASC) num name , city , score FROM scores num user_name city score 1 山田 太郎 Tokyo 10 2 鈴木 一郎 Tokyo 20 1 佐藤 太郎 Nagoya 30 2 田中 次郎 Nagoya 40 1 伊藤 太郎 Osaka 50
【関連記事】
▶【SQL】連番を振るROW_NUMBER関数を解説!一番よく使う順位付け関数をマスターしよう
Oracleのrow_number関数の構文
以下は、Oracleのrow_number関数の使用例です。hr.employees表で各部門の支給額の高いトップ3人の従業員のレコードを抽出します。従業員が3人未満の部門は、3行未満の行が戻されます。
SELECT department_id, first_name, last_name, salary FROM ( SELECT department_id, first_name, last_name, salary, ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary desc) rn FROM employees ) WHERE rn <= 3 ORDER BY department_id, salary DESC, last_name;
SQL Serverのrow_number関数の構文
SQL Serverのrow_numberの構文は以下の通りです。
ROW_NUMBER ( ) OVER ( [ PARTITION BY value_expression , ... [ n ] ] order_by_clause )
関連)ROW_NUMBER (Transact-SQL) – SQL Server | Microsoft Docs
以下のSQLは、sys.databasesテーブルのdatabase_idが5以下のデータベースに、nameを昇順にソートして連番を振っている例です。
SELECT ROW_NUMBER() OVER(ORDER BY name ASC) AS Row#, name, recovery_model_desc FROM sys.databases WHERE database_id < 5; Row# name recovery_model_desc 1 master SIMPLE 2 model FULL 3 msdb SIMPLE 4 tempdb SIMPLE
以下は、PARTITION BY指定をおこなって、SalesTerritoryKeyごとにグルーピングした上でグループごとに連番を振っています。
-- Uses AdventureWorks SELECT ROW_NUMBER() OVER(PARTITION BY SalesTerritoryKey ORDER BY SUM(SalesAmountQuota) DESC) AS RowNumber, LastName, SalesTerritoryKey AS Territory, CONVERT(varchar(13), SUM(SalesAmountQuota),1) AS SalesQuota FROM dbo.DimEmployee AS e INNER JOIN dbo.FactSalesQuota AS sq ON e.EmployeeKey = sq.EmployeeKey WHERE e.SalesPersonFlag = 1 GROUP BY LastName, FirstName, SalesTerritoryKey; RowNumber LastName Territory SalesQuota --------- ------------------ --------- ------------- 1 Campbell 1 4,025,000.00 2 Ansman-Wolfe 1 3,551,000.00 3 Mensa-Annan 1 2,275,000.00 1 Blythe 2 11,162,000.00 1 Carson 3 12,198,000.00 1 Mitchell 4 11,786,000.00 2 Ito 4 7,804,000.00 : :
MySQLでrow_number関数を使わず行番号をつける
MySQLには、row_number関数がありません。ユーザ変数を使って、行番号を振ることが可能です。
SET @rownum=0; SELECT @rownum:=@rownum+1 as num, first_name, last_name, hire_date FROM employees ORDER BY hire_date; +------+-------------+--------------+------------+ | num | first_name | last_name | hire_date | +------+-------------+--------------+------------+ | 1 | Tonny | Butterworth | 1985-01-01 | | 2 | Ebru | Alpin | 1985-01-01 | | 3 | Przemyslawa | Kaelbling | 1985-01-01 | | 4 | DeForest | Hagimont | 1985-01-01 | | 5 | Peternela | Onuegbe | 1985-01-01 | | 6 | Krassimir | Wegerle | 1985-01-01 | | 7 | Arie | Staelin | 1985-01-01 | | 8 | Margareta | Markovitch | 1985-01-01 | | 9 | Shirish | Ossenbruggen | 1985-01-01 | | 10 | Isamu | Legleitner | 1985-01-14 | : :
【関連記事】
▶SQLで行番号を取得する ROW_NUMBER・ROWNUM・ユーザ定義変数の使い方 |
PostgreSQLのrow_number関数の構文
以下は、PostgreSQLでrow_number関数を使用する例です。
SELECT product_id, product_name, group_id, ROW_NUMBER () OVER ( ORDER BY product_name ) FROM products;
関連)PostgreSQL ROW_NUMBER() Explained with Practical Examples
まとめ
- row_number関数は、連番を生成する関数
- partition byやorder byでグルーピング範囲とソート指定が可能
- MySQLにはrow_number関数がないが、ユーザ定義変数で代用可能