SQL 書き方ドリル
改訂新版 反復学習ソフト付き SQL書き方ドリル (WEB+DB PRESS plusシリーズ)
- 作者: 羽生章洋,和田省二
- 出版社/メーカー: 技術評論社
- 発売日: 2007/05/18
- メディア: 大型本
- 購入: 24人 クリック: 355回
- この商品を含むブログ (56件) を見る
評判が良さそうなので買ってみた。
第3章の「複数のテーブルを扱う」は勉強になった。
正直言うと、あまり複雑な SQL は書いたことがなかったりして...(^^;)
2、3 気になった点があったのでコメントしておく。
第3章 その2
都道府県別に、それぞれ何人ずつ顧客がいるのか教えてくれ。そうそう、この前は都道府県の名前が出ていなかったぞ。ID だけじゃわからないのでちゃんと表示してくれ。
/* 解答1 (テキストから一部自己流に変えています) */ SELECT p.PrefecturalID, p.PrefecturalName AS 都道府県名, COUNT(*) AS 顧客数 FROM Prefecturals AS p JOIN Customers AS c ON p.PrefecturalID = c.PrefecturalID GROUP BY p.PrefecturalID, p.PrefecturalName ;
/* 解答2 (テキストから一部自己流に変えています) */ SELECT p.PrefecturalID, MAX(p.PrefecturalName) AS 都道府県名, COUNT(*) AS 顧客数 FROM Prefecturals AS p JOIN Customers AS c ON p.PrefecturalID = c.PrefecturalID GROUP BY p.PrefecturalID ;
解答1と解答2はどちらが一般的なんでしょう?
パフォーマンスはそれほど変わらないのかな?
/* 解答3 (自分の解答) */ SELECT p.PrefecturalID, p.PrefecturalName AS 都道府県名, c.Count AS 顧客数 FROM Prefecturals AS p JOIN ( SELECT PrefecturalID, COUNT(*) AS Count FROM Customers GROUP BY PrefecturalID ) AS c ON p.PrefecturalID = c.PrefecturalID ;
自分としては、この SQL が一番しっくり来る気がします。
ただ、全件ではなく部分検索の場合、
SELECT p.PrefecturalID, p.PrefecturalName AS 県名, c.Count AS 顧客数 FROM Prefecturals AS p JOIN ( SELECT PrefecturalID, COUNT(*) AS Count FROM Customers GROUP BY PrefecturalID ) AS c ON p.PrefecturalID = c.PrefecturalID WHERE p.PrefecturalName LIKE '%県' ;
だと無駄な集計処理が行われちゃいますかね?
DBMS が適当に最適化してくれるとうれしいんですが。
SELECT p.PrefecturalID, p.PrefecturalName AS 県名, c.Count AS 顧客数 FROM Prefecturals AS p JOIN ( SELECT PrefecturalID, COUNT(*) AS Count FROM Customers WHERE PrefecturalID IN ( SELECT PrefecturalID FROM Prefecturals WHERE PrefecturalName LIKE '%県' ) GROUP BY PrefecturalID ) AS c ON p.PrefecturalID = c.PrefecturalID ;
それともこんなふうに書いた方がいいですかね。
例題のように Prefecturals から SELECT するカラムが1個だけならここまでしませんが、複数カラムだったり、さらに別のテーブルと JOIN する場合、どうしようか少し悩んでいます。
第3章 その6
商品ごとの販売数量の平均を上回った日を一覧で出してくれ。商品単位で比較してくれよ。あ、商品名は当然つけてくれよ。
/* 解答1 (テキストから一部自己流に変えています) */ SELECT p.ProductName, s.SaleDate FROM Products AS p JOIN Sales AS s ON p.ProductID = s.ProductID WHERE s.Quantity > ( SELECT AVG(Quantity) FROM Sales AS s2 WHERE s.ProductID = s2.ProductID ) ORDER BY p.ProductID, s.SaleDATE DESC ;
これがテキストの解答なんだけど...
/* 解答2 (自分の解答) */ SELECT p.ProductName, s.SaleDate FROM Products AS p JOIN Sales AS s ON p.ProductID = s.ProductID JOIN ( SELECT ProductID, AVG(Quantity) AS AvgQuantity FROM Sales GROUP BY ProductID ) AS s2 ON s.ProductID = s2.ProductID AND s.Quantity > s2.AvgQuantity ORDER BY p.ProductID, s.SaleDATE DESC ;
こちらの方がパフォーマンスが良くないでしょうか?