システム監査技術者 2012年 午前2 問17
問題文
“商品”表に対して、次のSQL文を実行して得られる仕入先数は幾つか。
SELECT DISTINCT 仕入先コード FROM 商品
WHERE (販売単価 - 仕入単価) >
(SELECT AVG (販売単価 - 仕入単価) FROM 商品)

選択肢
ア:1
イ:2
ウ:3(正解)
エ:4
🔒 解説は解答すると表示されます
粗利益の平均と仕入先の抽出【午前2解説】
正解の理由
販売単価から仕入単価を引いた値は、商品ごとの粗利益です。まず、全商品の粗利益の平均を求めます。
粗利益は商品順に、200円、200円、100円、900円、400円、200円、300円、500円、500円、300円です。合計は3,600円、商品数は10個なので、平均は次のとおりです。
この平均360円を超える商品は、D(900円)、E(400円)、H(500円)、I(500円)です。それぞれの仕入先コードはS1、S1、S4、S5です。
SQLでは
DISTINCT によって仕入先コードの重複が取り除かれるため、該当する仕入先はS1、S4、S5の3つです。したがって、ウが正解です。解法ステップ
- 商品ごとに「販売単価 − 仕入単価」を計算します。
- 全商品の粗利益の平均を求めます。平均は360円です。
- 粗利益が360円を超える商品を選びます。条件は「以上」ではなく「より大きい」です。
- 該当商品の仕入先コードを確認します。S1、S1、S4、S5です。
DISTINCTによって重複するS1を一つにまとめ、仕入先数を数えます。
選択肢別の誤答解説
- ア(1):平均を超える商品が複数あり、仕入先コードもS1だけではありません。異なる仕入先を数える際に、該当商品や仕入先を見落とした可能性があります。
- イ(2):仕入先コードの重複を除く操作は必要ですが、該当するコードは2種類ではありません。該当商品ごとにコードを確認し、異なるコードをすべて数えます。
- ウ(3):平均360円を超える商品の仕入先コードはS1、S4、S5の3種類です。
- エ(4):平均を超える商品は4個ですが、仕入先コードS1が2回登場します。商品数ではなく、
DISTINCTで重複を除いた仕入先数を数えます。
よくある誤解
- 平均を超える商品数と、仕入先数を混同する
条件を満たす商品は4個ですが、重複を除いた仕入先数は3です。 DISTINCTを平均計算にも適用すると考える
DISTINCTが適用されるのは、SELECT句で指定された仕入先コードです。副問合せの平均は、商品表の全行を対象に計算されます。- 「>」を「以上」と読み違える
条件は平均値を含みません。粗利益が360円ちょうどの商品があれば、対象外です。
補足コラム
このSQLの副問合せは、商品表全体の粗利益の平均を1つの値として返します。外側のWHERE句は、各商品の粗利益をその平均値と比較します。
また、SELECT句の
DISTINCT は、条件を満たした行の仕入先コードから重複を除きます。そのため、仕入先数を求める問題では、最後に「該当行数」ではなく「異なる仕入先コード数」を数えることが大切です。FAQ
Q. 平均値は仕入先ごとに計算しますか?
A. いいえ。この副問合せには仕入先ごとに集計する指定がないため、商品表全体で平均を計算します。
A. いいえ。この副問合せには仕入先ごとに集計する指定がないため、商品表全体で平均を計算します。
Q. S1の商品が2つあるのに、仕入先数に2つと数えないのはなぜですか?
A.
A.
DISTINCT が同じ仕入先コードの重複を除くためです。S1は一つとして数えます。関連キーワード: SQL、DISTINCT、副問合せ、集約関数、平均値、WHERE句

\ せっかくなら /
システム監査技術者を
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

