3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Db2 : FETCH FIRST n ROWSとOFFSET、およびLIMIT代替構文(続き)-副選択で使う

Last updated at Posted at 2018-07-27

前回の続きです。
Db2 : FETCH FIRST n ROWSとOFFSET、およびLIMIT代替構文

Db2 11.1では、PostgreSQLやMySQLなどで使用されるLIMIT ... OFFSETといった代替構文も使用できるようになりました。

副選択(subselect)でFETCH FIRSTとOFFSETを使う

FETCH FIRST/OFFSET節を使って SELECTでn行までしか取得しないように限定する書き方ですが、副選択(subselect)照会で使うこともできます。

こちらはDb2のSAMPLEデータベースのEMPLOYEE表を使っています。

例えば、
「3番目にサラリー平均の高い部門の値よりも多くのサラリーをもらっている従業員の名前を知りたい」

という場合、(いろいろなアプローチが考えられますが)、その一つの例として以下のように書くことができます。

まず、各部門における平均サラリーを見てみます。

SELECT WORKDEPT, AVG(SALARY) FROM EMPLOYEE
GROUP BY WORKDEPT
ORDER BY AVG(SALARY) DESC

WORKDEPT 2
-------- ---------------------------------
B01         94250.000000000000000000000000
E01         80175.000000000000000000000000
C01         77222.500000000000000000000000
A00         70850.000000000000000000000000
D11         58783.636363636363636363636363
D21         51240.000000000000000000000000
E21         47086.666666666666666666666666
E11         45305.714285714285714285714285

  8 レコードが選択されました。

「3番目にサラリー平均が高い部門の値」が欲しいので、FETCH FIRSTとOFFSETを使います。
つまり、2行スキップして3番目の値を取得します。

SELECT WORKDEPT, AVG(SALARY) FROM EMPLOYEE GROUP BY WORKDEPT 
ORDER BY AVG(SALARY) DESC 
OFFSET 2 ROWS FETCH FIRST 1 ROWS ONLY
WORKDEPT 2
-------- ---------------------------------
C01         77222.500000000000000000000000

  1 レコードが選択されました。

これを副選択照会(subselect)に使って、3番目にサラリー平均の高い部門の値よりも多くのサラリーをもらっている従業員の名前、をリストします。

SELECT LASTNAME, SALARY FROM EMPLOYEE 
	WHERE     
		SALARY > (       
			SELECT AVG(SALARY) FROM EMPLOYEE         
				GROUP BY WORKDEPT         
				ORDER BY AVG(SALARY) DESC         
				OFFSET 2 ROWS FETCH FIRST 1 ROW ONLY       
			)
ORDER BY SALARY
LASTNAME        SALARY
--------------- -----------
GEYER              80175.00
SPENSER            86150.00
HENDERSON          89750.00
THOMPSON           94250.00
PULASKI            96170.00
KWAN               98250.00
HAAS              152750.00

  7 レコードが選択されました。

LIMIT ... OFFSETの代替構文を使ってみる

Db2 11.1では、PostgreSQLやMySQLなど他のデータベース製品で使用されるSQLも簡単にDb2環境で実行できるようにする機能拡張が含まれており、FETCH FIRST ... OFFSET節の代替として、シンプルにLIMIT/OFFSETを指定することもできるようになりました。

代替構文 同等の構文
LIMIT x FETCH FIRST x ROWS ONLY
LIMIT x OFFSET y OFFSET y ROWS FETCH FIRST x ROWS ONLY
LIMIT y,x OFFSET y ROWS FETCH FIRST x ROWS ONLY

こちらを使って同じ結果を取得してみます。

SELECT WORKDEPT, AVG(SALARY) FROM EMPLOYEE 
GROUP BY WORKDEPT 
ORDER BY AVG(SALARY) DESC 
LIMIT 1 OFFSET 2
WORKDEPT 2
-------- ---------------------------------
C01         77222.500000000000000000000000

  1 レコードが選択されました。

それでは、3番目にサラリー平均の高い部門の値よりも多くのサラリーをもらっている従業員の名前をリストします。
"LIMIT x OFFSET y"は、"LIMIT x,y"ではなく、"LIMIT y,x"であることに注意(!)

SELECT LASTNAME, SALARY FROM EMPLOYEE
	WHERE
		SALARY > (
			SELECT AVG(SALARY) FROM EMPLOYEE
				GROUP BY WORKDEPT
				ORDER BY AVG(SALARY) DESC
				LIMIT 2,1
			)
ORDER BY SALARY

LASTNAME        SALARY
--------------- -----------
GEYER              80175.00
SPENSER            86150.00
HENDERSON          89750.00
THOMPSON           94250.00
PULASKI            96170.00
KWAN               98250.00
HAAS              152750.00

  7 レコードが選択されました。

少しシンプルになりました。

参考資料

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?