NATURAL JOINでは、次のファンクションが暗黙的に実行されます。
NATURALキーワードが問合せに指定されている場合は、明示的な結合条件を指定できません。次に、自然結合の例を示します。共通列C1の表示は1回のみです。他のタイプの結合条件からは、表の参照で発生する回数分の共通列が返されます。
SQL> SELECT * cont> FROM TABLE1 NATURAL LEFT OUTER JOIN TABLE2; C1 TABLE1.C2 TABLE2.C4 10 15 AA 20 25 CC 30 35 NULL 3 rows selected |
次の例は、前の例に示すNATURAL LEFT OUTER JOINを明示的に実行する複雑さを示しています。
SQL> SELECT cont> COALESCE (TABLE1.C1, TABLE2.C1) AS C1, cont> TABLE1.C2, TABLE2.C4 cont> FROM TABLE1 LEFT OUTER JOIN TABLE2 cont> ON TABLE1.C1 = TABLE2.C1; C1 TABLE1.C2 TABLE2.C4 10 15 AA 20 25 CC 30 35 NULL 3 rows selected |
NATURALキーワードは、INNER結合、LEFT OUTER結合、RIGHT OUTER結合およびFULL OUTER結合に対して指定できます。
名前付きの一致する列を共有しない2つの表参照間の自然結合は、デカルト積になります。
SQL> DELETE FROM EMPLOYEES E cont> WHERE EXISTS ( SELECT * cont> FROM SALARY_HISTORY S cont> WHERE S.EMPLOYEE_ID = E.EMPLOYEE_ID cont> AND S.SALARY_AMOUNT > 75000) cont> OPTIMIZE AS DEL_EMPLOYEE; Leaf#01 FFirst RDB$RELATIONS Card=19 . . . ~Query Name : DEL_EMPLOYEE . . . 7 rows deleted |
SQL> DECLARE TEMP1 TABLE CURSOR cont> FOR cont> SELECT * cont> FROM EMPLOYEES cont> WHERE EMPLOYEE_ID > '00400' cont> OPTIMIZE FOR FAST FIRST; SQL> -- SQL> DECLARE TEMP2 TABLE CURSOR cont> FOR cont> SELECT LAST_NAME, FIRST_NAME cont> FROM EMPLOYEES cont> ORDER BY LAST_NAME cont> OPTIMIZE FOR TOTAL TIME; |
SQL> delete from PARTS_LOG cont> where parts_id between 10000 and 20000 cont> and expire_date < :purge_date cont> optimize for sequential access; |
このような問合せで行われるアクセスはすべて順次アクセスです。索引アクセスを使用する同様の問合せを比較して、使用中のI/Oが受け入れられるかに注意します。
次の例では、WOMENS_DEGREESという名前のアウトラインを作成する問合せを示します。
SQL> SELECT E.LAST_NAME, E.EMPLOYEE_ID, D.DEGREE, D.DEGREE_FIELD, D.YEAR_GIVEN cont> FROM EMPLOYEES E, DEGREES D WHERE E.SEX = 'F' cont> AND E.EMPLOYEE_ID = D.EMPLOYEE_ID cont> ORDER BY LAST_NAME |
OPTIMIZE USING句を使用してWOMENS_DEGREESアウトラインを指定すると、次の例に示すように、わずかに異なる問合せを実行する場合でも、Oracle Rdbでは、WOMENS_DEGREESアウトラインの使用が試行されます。
SQL> SELECT E.LAST_NAME, E.EMPLOYEE_ID, D.DEGREE, D.DEGREE_FIELD, D.YEAR_GIVEN cont> FROM EMPLOYEES E, DEGREES D WHERE E.SEX = 'F' cont> AND E.EMPLOYEE_ID = D.EMPLOYEE_ID cont> ORDER BY LAST_NAME cont> LIMIT TO 10 ROWS cont> OPTIMIZE USING WOMENS_DEGREES; ~S: Outline WOMENS_DEGREES used <-- the query uses the WOMENS_DEGREES outline . . . E.LAST_NAME E.EMPLOYEE_ID D.DEGREE D.DEGREE_FIELD D.YEAR_GIVEN Boyd 00244 MA Elect. Engrg. 1982 Boyd 00244 PhD Applied Math 1979 Brown 00287 BA Arts 1982 Brown 00287 MA Applied Math 1979 Clarke 00188 BA Arts 1983 Clarke 00188 MA Applied Math 1976 Clarke 00196 BA Arts 1978 Clinton 00235 MA Applied Math 1975 Clinton 00201 BA Arts 1973 Clinton 00201 MA Applied Math 1978 10 rows selected |
アウトラインの作成方法の詳細は、「CREATE OUTLINE文」を参照してください。
ORDER BY句の列は、次の2つの方法で参照できます。
選択リストの列がファンクション、演算式、またはUNION、MINUS、EXCEPT、INTERSECT演算子の結果のいずれかから派生している場合は、整数を使用してORDER BY句の列を識別する必要があります。
ORDER BY句の式の識別に名前または数値のいずれを使用しているかに関係なく、式はソート・キーと呼ばれます。
複数のソート・キーを使用すると、最初の式がメジャー・ソート・キー、後続のキーがマイナー・ソート・キーとして処理されます。つまり、行はまず最初の値式に基づいてグループ化されます。次に、2番目の値式を使用して各グループ内で行がソートされ、同様の処理が繰り返されます。結果表のすべての列に対してソート・キーを指定しないかぎり、指定された最後のソート・キーと同じ値のある行は任意の順序になります。
次の例は、値式を使用したORDER BY句の使用方法を示しています。
SQL> SELECT * FROM EMPLOYEES cont> ORDER BY EXTRACT (YEAR FROM BIRTHDAY), cont> TRIM(FIRST_NAME) || TRIM(LAST_NAME); 00190 O'Sullivan Rick G. 78 Mason Rd. NULL Fremont NH 03044 M 12-Jan-1923 1 None 00231 Clairmont Rick NULL 92 Madiso7 Drive NULL Chocorua NH 03817 M 23-Dec-1924 2 None 00183 Nash Walter V. 197 Lantern Lane NULL Fremont NH 03044 M 19-Jan-1925 1 None 00177 Kinmonth Louis NULL 76 Maple St. NULL Etna NH 03750 M 7-Apr-1926 1 None 00240 Johnson Bill R. 20 South St NULL Milford NH 03055 M 13-Apr-1927 2 None . . . |
INNER JOINおよびOUTER JOINでは、最初の表参照のすべての列を2番目の表参照のすべての列に組み合せたものが結果表になります。NATURAL JOINでは、表参照間で共通列(同名の列)を要約したものが結果表になります。詳細は、次の引数を参照してください。
SQL> SELECT * cont> FROM TABLE1 RIGHT OUTER JOIN TABLE2 cont> ON TABLE1.C1 = TABLE2.C1; TABLE1.C1 TABLE1.C2 TABLE2.C1 TABLE2.C4 10 15 10 AA NULL NULL 15 BB 20 25 20 CC 3 rows selected |
FULL OUTER JOINの例は、INNER JOINの例の結果にTABLE1およびTABLE2の一致しない行を追加したものと同じになります。
ワイルドカードを使用するか、または値式を明示的にリストすると、選択リストに指定する列の数は、次の結果表の列の数になります。
次の例では、給与が$50,000を超え博士号を持っている現在の従業員のEMPLOYEE_IDが抽出されます。重複している行は結果表から除去されます。
SQL> SELECT EMPLOYEE_ID cont> FROM CURRENT_SALARY cont> WHERE SALARY_AMOUNT > 50000 cont> UNION cont> SELECT EMPLOYEE_ID cont> FROM DEGREES cont> WHERE DEGREE = 'PhD'; EMPLOYEE_ID 00164 00166 00168 00169 00172 00182 . . . 00418 00435 00471 38 rows selected |
次の例では、結果表から重複している行が返されます。
SQL> SELECT LAST_NAME, SEX FROM EMPLOYEES WHERE LAST_NAME = 'Nash' cont> UNION ALL cont> SELECT LAST_NAME, SEX FROM EMPLOYEES WHERE LAST_NAME = 'Lapointe'; LAST_NAME SEX Nash M Nash M Lapointe F Lapointe F 4 rows selected |
SQL> SELECT * cont> FROM TABLE1 LEFT OUTER JOIN TABLE2 cont> USING (C1); C1 TABLE1.C2 TABLE2.C4 10 15 AA 20 25 CC 30 35 NULL 3 rows selected |
前の例に示すように、結果として共通列は単一列に結合されます。したがって、このような列は修飾できません。結合列は問合せで参照できます。次に例を示します。
SQL> SELECT * cont> FROM TABLE1 LEFT OUTER JOIN TABLE2 cont> USING (C1) cont> WHERE C1 BETWEEN 20 AND 30; C1 TABLE1.C2 TABLE2.C4 20 25 CC 30 35 NULL 2 rows selected |
WHERE句の条件で指定する列名は、次のいずれかである必要があります。
通常、WHERE句内の条件では集計関数を参照できません。たとえば、次の文は無効です。
SQL> SELECT * FROM EMPLOYEES WHERE MAX(LAST_NAME) > 'X'; %SQL-F-INVFUNREF, Invalid function reference |
この制限範囲の例外については、この項の「使用方法」を参照してください。
SQL> SELECT * FROM JOBS, CURRENT_JOB JOBS; %SQL-F-CONVARDEF, Column qualifier JOBS is already defined SQL> -- SQL> SELECT * FROM JOBS J, CURRENT_JOB J; %SQL-F-CONVARDEF, Column qualifier J is already defined |
SQL> -- Display departments that have total current SQL> -- salaries greater than their projected budget: SQL> SELECT DEPARTMENT cont> FROM CURRENT_INFO cont> GROUP BY DEPARTMENT cont> HAVING DEPARTMENT IN cont> (SELECT DEPARTMENT_NAME cont> FROM DEPARTMENTS cont> WHERE SUM (CURRENT_INFO.SALARY) > BUDGET_PROJECTED); 0 rows selected |
たとえば、次の問合せはファンクションと列名が混在しているため、評価できません。
SQL> SELECT EMPLOYEE_ID, AVG(SALARY_AMOUNT) cont> FROM SALARY_HISTORY; %SQL-F-INVSELLIS, Select list cannot mix columns and functions without GROUP BY |
GROUP BY句なしでファンクションのリストを指定すると、選択式によって生成される結果表に含まれる行は1行のみになります。
たとえば、次の文は無効です。
SQL> SELECT LAST_NAME, FIRST_NAME FROM EMPLOYEES cont> GROUP BY LAST_NAME ; |
ただし、SQLでは、ワイルドカードはGROUP BY句で指定した列名のみを参照すると解釈されるため、選択リストでワイルドカードを使用できます。
たとえば、次の文は有効です(この場合、ワイルドカードはLAST_NAME列のみを指定します)。
SQL> SELECT * FROM EMPLOYEES cont> GROUP BY LAST_NAME ; |
SQL> select manager_id from departments cont> except distinct cont> select employee_id from employees; |
この問合せは次のように再度記述することができます。
SQL> select manager_id cont> from departments d cont> where not exists (select * cont> from employees e cont> where e.employee_id = d.manager_id cont> or (e.employee_id is null cont> and d.manager_id is null)); |
このように単純な問合せでもEXCEPT書式が読みやすくなります。選択する列数が増加すると、それに応じてNOT EXISTS副問合せも複雑になります。
SQL> select manager_id from departments cont> intersect distinct cont> select employee_id from employees; |
この問合せは次のように再度記述することができます。
SQL> select manager_id cont> from departments d cont> where exists (select * cont> from employees e cont> where e.employee_id = d.manager_id cont> or (e.employee_id is null cont> and d.manager_id is null)); |
このように単純な問合せでもINTERSECT書式が読みやすくなります。選択する列数が増加すると、それに応じてEXISTS副問合せも複雑になります。