SELECT | * |
FROM | EMP |
WHERE | EMP.DEPTNO = ( SELECT MIN(DEPT.DEPTNO) FROM DEPT) |
WHEREのあとのEMP.DEPTNOと、別のSELECT文の問合せ結果との比較をしています。このような問合せを副問合せといいます。
カッコ内側のSELECT MIN(DEPT.DEPTNO) FROM DEPT)で抽出された、MIN(DEPT.DEPTNO)とEMP.DEPTNOを比較し、等しいレコードを抽出します。
この場合、内側のSELECT文の後に書かれてある項目(ここではMIN(DEPT.DEPTNO) )は、EMP.DEPTNOと比較可能なものである必要があります。
例えば、内側の問合せがSELECT DEPT.DEPTNO FROM DEPTだと、複数のレコードを返してくるので、エラーになります。
SELECT | * |
FROM | EMP |
WHERE | DEPTNO IN (10,30) |
INを使用すると()に囲まれているものを含むレコードを抽出できます。
上記の例だと、DEPTNO = 10 OR DEPTNO = 30 と同じ意味になります。
否定をする場合はNOT IN のようにINの直前にNOTを付けます。
それでは実習です。2題出題します。
SELECT | * |
FROM | EMP |
WHERE | DEPTNO IN (SELECT DEPTNO FROM DEPT WHERE DNAME LIKE '%S%') |
入れ子の問合せは、()の中がSQLのSELECT文に変わるだけです。内側のSQLが実行され(20,30,40)が抽出されIN (20,30,40)が実行されます。
ソフトウェア開発技術者午前平成15年問73社員番号 | 社員名 | 部門 | 居室番号 |
001 | 田中 | A1 | 110 |
002 | 鈴木 | A1 | 111 |
003 | 佐藤 | A1 | 203 |
004 | 福田 | A2 | 201 |
005 | 渡辺 | A2 | 202 |
部屋番号 | 部門 |
110 | A1 |
111 | A1 |
201 | A2 |
202 | A2 |
203 | A2 |
SELECT | 社員名 | ||||||
FROM | 社員の居室 | ||||||
WHERE | 居室番号 NOT IN (
|
ア
|
イ
|
ウ
|
エ
|
SELECT | ENAME,SAL |
FROM | EMP EA |
WHERE | NOT EXISTS( |
SELECT * FROM EMP EB | |
WHRE EB.SAL > EA.SAL | |
) |
このSQLはEXISTS記述を使って、給料が最も高い従業員の抽出を行っています。
EXISTS記述は()の中に書いてあるSQLで抽出されるレコードがある場合は真、無い場合は偽を返してきます。真のときのみ外側のWHERE条件が成立し、レコードが抽出されます。
実際の動作は外側のEMP表(EA)から一行ずつ取り出され、内側のSQLで比較されます。
EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800 | 20 | |
7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600 | 300 | 30 |
7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250 | 500 | 30 |
7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975 | 20 | |
7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250 | 1400 | 30 |
7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850 | 30 | |
7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450 | 10 | |
7839 | KING | PRESIDENT | 1981-11-17 | 5000 | 10 | ||
7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500 | 0 | 30 |
7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950 | 30 | |
7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000 | 20 | |
7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300 | 10 |
EMP表のEA側の一行(SMITHの給料の800)が取り出されます。これを用いて内側のSQLでEB.SAL > EA.SALの比較が行われます。EA.SALは800なので内側のSQLはレコードを返し、EXISTSは真となります。NOTで否定しているので、答えは偽となり、SMITHのレコードは抽出されません。
上から順番にデータが取り出され、KINGの行までくると、KINGのSALは5000ですから、内側のSQLはレコードを抽出しないので、EXISTSは偽となり、NOTで真になるので、KINGのレコードは抽出されます。
これで [ 入れ子の問合せ ] は終了です。