助け合いフォーラム
最高給与の従業員名と給与、給与等級を表示する以下のSQL文を作成しました。
従業員の給与等級は、EMPLOYEES表のSALARY列の値と、GRADE表のLOW列からHIGH列の値の範囲で決定します。
SELECT employee_name, salary, grade FROM employees, grade
WHERE salary = (SELECT MAX(salary) FROM employees)
AND salary BETWEEN low AND high
ORDER BY 3, 2 DESC, 1
これと同じ実行結果となるSQL文はどれですか(2つ選択して下さい)。
正解
SELECT employee_name, salary, grade FROM employees, grade
WHERE salary IN (SELECT MAX(salary) FROM employees)
AND salary BETWEEN low AND high
ORDER BY 3, 2 DESC, 1;
SELECT employee_name, salary, grade FROM employees, grade
WHERE salary BETWEEN low AND high
AND salary = (SELECT MAX(salary) FROM employees)
ORDER BY 3, 2 DESC, 1;
解説
Oracle独自の結合構文ではWHERE句に結合条件を指定します。
非等価結合は、結合条件に=(等号演算子)以外の演算子を用いて、条件を満たすデータを取り出す結合です。非等価結合では、結合条件に<,>,<=,>=,BETWEEN等の演算子を使用します。
設問では、WHERE句の2番目の条件「salary BETWEEN low AND high」でEMPLOYEES表のSALARY列の値がGRADE表のHIGH列とLOW列の値の範囲内である行を結合し、従業員の給与等級を表示しています。
また、WHERE句の1番目の副問合せでEMPLOYEES表の最高給与を検索しています。
以下の2つのSQL文が設問と同じ条件を満たし、正解となります。
・SELECT employee_name, salary, grade FROM employees, grade
WHERE salary IN (SELECT MAX(salary) FROM employees)
AND salary BETWEEN low AND high
ORDER BY 3, 2 DESC, 1;
・SELECT employee_name, salary, grade FROM employees, grade
WHERE salary BETWEEN low AND high
AND salary = (SELECT MAX(salary) FROM employees)
ORDER BY 3, 2 DESC, 1;
正解のSQL文の実行結果は次のようになります。
WHERE salary IN (SELECT MAX(salary) FROM employees)
AND salary BETWEEN low AND high
ORDER BY 3, 2 DESC, 1;
WHERE salary BETWEEN low AND high
AND salary = (SELECT MAX(salary) FROM employees)
ORDER BY 3, 2 DESC, 1;
その他の選択肢については以下のとおりです。
・SELECT employee_name, salary, grade FROM employees, grade
WHERE (SELECT MAX(salary) FROM employees) BETWEEN low AND high
ORDER BY 3, 2 DESC, 1;
WHERE句に結合条件が指定されていないため、全従業員と給与等級「B」が表示されます。誤ったSQL文です。
・SELECT employee_name, salary, grade FROM employees, grade
WHERE salary = (SELECT MAX(salary) FROM employees)
AND MAX(salary) BETWEEN low AND high
ORDER BY 3, 2 DESC, 1;
WHERE句にグループ関数MAX(salary)を指定しているのでエラーとなります。誤ったSQL文です。
参考
構文は以下の通りです。
SELECT [表接頭辞.]列名 [, [表接頭辞.]列名 ...]
FROM 表名1, 表名2
WHERE 結合条件
[AND 結合条件以外の条件];
FROM departments d, employees e
WHERE d.department_id = e.department_id
AND salary BETWEEN 200000 AND 450000;
Oracle独自の結合構文では、
・結合する表名は,(カンマ)で区切ってFROM句に指定
・結合条件はWHERE句に指定
・結合条件以外の条件はWHERE句に指定した結合条件の後にAND演算子で指定
します。
ON句を使用した結合同様に、結合する2つの表にある同じ名前の列をSELECT句やWHERE句に指定する場合は、必ず表接頭辞を使用して列を指定しなければなりません。
FROM departments d, employees e
WHERE d.department_id = e.department_id
AND salary BETWEEN 200000 AND 450000;
なお、以下はOracle Databaseで使用できる表の結合方法(ANSI SQL:1999準拠の結合構文)で、〇がついているものはOracle独自の結合構文でも記述できます。
SQL:1999準拠の結合構文とOracle独自の結合構文とではパフォーマンスに違いはありません。
DESCの後の数字について
下記のDESCの後に表示されている「1」は何をあらわしているのでしょうか。
SELECT employee_name, salary, grade FROM employees, grade
WHERE salary = (SELECT MAX(salary) FROM employees)
AND salary BETWEEN low AND high
ORDER BY 3, 2 DESC, 1
ORDER BY 3, 2 DESC, 1 となっているので、grade,salaryで降順、
そして1(employee_name)では昇順という認識で合っていますでしょうか?
下記のDESCの後に表示されている「1」は何をあらわしているのでしょうか。
これは、ORDER BY 句における項目の指定方法で、列名や列別名以外に、SELECT句で指定した項目の順番を数値で指定することができるというものです。
DESCの後の数字というか、DESCはその前の数字にかかっています。
SELECT employee_name, salary, grade FROM employees, grade
WHERE salary = (SELECT MAX(salary) FROM employees)
AND salary BETWEEN low AND high
ORDER BY 3, 2 DESC, 1
この例だと、まず最初に「3」(grade)で昇順にソート、次に「2」(salary)で降順にソート、最後に「1」(employee_name)で昇順にソート、という動きになります。
※ORDER BY句のデフォルトが昇順で、ASCは省略可能、降順にしたい場合はDESCを指定する。
ORDER BY句に着目した別の問題(26443)に、以下の説明がありました。
ORDER BY句の項目には「列名」の他、以下を指定できます。どれも重要です。
・列別名(*WHERE句では指定不可)
・算術式
・SELECT句に指定されている項目の順番(数値)
ASCとDESCは昇順/降順を指定するキーワードです。ASCで昇順(小さい順)、DESCで降順(大きい順)にソートします。省略するとASCが指定されたものとみなされます。
ORDER BY句では複数の項目を指定できますが、ASC/DESCも項目ごとに指定できます。
コメント
この投稿に対して返信しませんか?
n nanamit
2024/03/12 18:19
rink_rew さん ご丁寧な回答ありがとうございます。 ORDER BYの後に3, 2 DESC,1 と指定してそれぞれソートできるのですね。 よくわかりました。ありがとうございます!