SQL Server

SELECT文

SELECT文は指定したデータを取得・出力するクエリです。出力する対象にはテーブルのカラムを指定することが多いですが、任意の出力したい数値や文字を指定することもできます。

SELECT文は6つの句から成ります。記述順に、SELECT句・FROM句・WHERE句・GROUP BY句・HAVING句・ORDER BY句です。SELECT句以外は省略することができますが省略した場合でも記述順は守らなければなりません。

SELECT句

SELECT句では出力対象となるデータを指定します。また、関数を使ってデータを加工することもできます。SELECT文を構成する6つの句のうち、SELECT句だけは省略不可となっています。基本的な文法は次の通りです。

SELECT ALL/DISTINCTオプション TOPオプション 出力対象1 AS ヘッダー名, 出力対象2 AS ヘッダー名, 出力対象n AS ヘッダー名 ;

ALL/DISTINCTオプション

重複したレコードの出力の是非を決めるオプションです。ALLを指定すると重複が許可されます。DISTINCTを指定すると重複したレコードは1レコードにまとめられて出力されます。どちらも指定しなかったときはALLで指定されます。

-- 重複レコードをまとめない SELECT ALL * ; -- 重複レコードをまとめる SELECT DISTINCT * ; -- 省略した場合はALL指定として処理される SELECT * ;

TOPオプション

TOPオプションはTOPオプションを指定しなかったときに出力される結果のうち、上位何件を表示するかを指定するオプションです。件数の指定には具体的な件数を指定する方法と、本来の出力件数に対する割合を指定する方法の2通りがあります。

-- 値指定(以下例では上位5件まで表示する) SELECT TOP(5) * ; -- 割合指定(以下例では上位30%を出力する) SELECT TOP(30) PERCIENT * ;

なお、TOPオプション直後の小括弧は省略することができますが推奨されません。

SELECT TOP 5 * ; SELECT TOP 30 PERCIENT * ;

出力対象の指定方法

出力対象の指定には3つ方法があります。

1つ目は直接値を指定する方法です。

-- 3と出力 SELECT 1 + 2 ; -- 12と出力 SELECT '1' + '2' ;

2つ目はFROM句で指定したテーブルに含まれるカラムを指定する方法です。

SELECT name, price FROM table_1 ;

3つ目はCASE式を使う方法です。CASE式は同じレコードに属する別カラムの値に応じて出力する値を変化させることができます。

SELECT name, price, CASE WHEN price => 10000 WHEN 'High-end' WHEN price < 1000 WHEN 'Low-end' ELSE 'Middle-range' FROM table_1 ;

ヘッダー名変更

SELECT文によって出力された結果のヘッダー名は変更することができます。ASキーワードの後ろに別名を記述します。

SELECT name AS '商品名', price AS '売価' FROM table_1 ;

ASは省略することもできます。

SELECT name '商品名', price '売価' FROM table_1 ;

FROM句

FROM句ではSELECT文で取得するデータを指定します。対象にはテーブルの他、テーブル変数などもFROM句で指定することができます。

-- 文法 SELECT * FROM 取得するデータ対象1 WITHオプション AS テーブル別名, 取得するデータ対象2 WITHオプション AS テーブル別名, 取得するデータ対象3 WITHオプション AS テーブル別名 ;

複数のテーブルを指定したとき、SELECT句で指定するカラム名はテーブル名.カラム名で指定します。ASキーワードを使ってテーブルの別名を指定したときは本来のテーブル名と別名、どちらを使っても問題ありません。

SELECT table_1.name, t1.price, table_2.name, t2.price FROM table_1 AS t1, table_2 AS t2 ;

WITHオプション

WITHオプションを付与すると、WITHオプションを指定しなかったときよりも弱いロックでクエリを実行することができます。何らかの処理が行われているテーブルからデータを取得したとき、あるいはSELECT文を実行したことで他のクエリの処理の邪魔をしたくないときに便利です。

注意すべき点としてはWITHオプションを含めて、SQL Serverでは全くロックを掛けないクエリというのは実行できません。そのため一部のクエリと並行して実行すると問題が起きることがあります。

SELECT * FROM table_1 WITH(NOLOCK) ;

JOIN演算子

JOIN演算子は2つのテーブルを結合して、初めから1つのテーブルであったかのような振る舞いを実現する演算子です。JOIN演算子はさらにCROSS JOIN演算子INNER JOIN演算子LEFT OUTER JOIN演算子RIGHT OUTER JOIN演算子FULL OUTER JOIN演算子の5つに分けられます。

CROSS JOIN演算子は2つのテーブル同士を掛け合わせた全ての組み合わせを出力します。つまり、3レコードのテーブルと3レコードのテーブルをCROSS JOIN演算子で結合すると、3 * 3 で9レコードのテーブルとして扱われるわけです。正直使い道はあまりありません。

SELECT * FROM table_1 CROSS JOIN table_2 ; -- 実は以下クエリでも同じ結果が得られます SELECT * FROM table_1, table_2 ;

INNER JOIN演算子は結合条件で指定した条件を満たすレコードのみ結合・出力します。処理の流れとしては、1.演算子左辺のテーブルの1行目を確認2.結合条件を満たした演算子右辺のレコードと結合3.結合されていたら出力し、そうでないなら出力しない4.演算子左辺のレコードの次行を参照するという流れになります。

SELECT * FROM table_1 INNER JOIN table_2 ON table_1.id = table_2.id ;

LEFT OUTER JOIN演算子はINNER JOIN演算子と似ていますが、演算子左辺のレコードに限っては結合していなくても出力します。反対に、RIGHT OUTER JOIN演算子は演算子右辺のレコードに限っては結合していなくても出力します。そして、FULL OUTER JOIN演算子は演算子両辺のテーブルに格納されたレコードを少なくとも1回は出力します。ちなみにOUTERキーワードは省略してもかまいません。

-- LEFT OUTER JOIN演算子例文 SELECT * FROM table_1 LEFT OUTER JOIN table_2 ON table_1.id = table_2.id ; -- RIGHT OUTER JOIN演算子例文 SELECT * FROM table_1 RIGHT OUTER JOIN table_2 ON table_1.id = table_2.id ; -- FULL OUTER JOIN演算子例文 SELECT * FROM table_1 FULL OUTER JOIN table_2 ON table_1.id = table_2.id ; -- OUTERキーワードを省略しても問題無い SELECT * FROM table_1 LEFT JOIN table_2 ON table_1.id = table_2.id ; SELECT * FROM table_1 RIGHT JOIN table_2 ON table_1.id = table_2.id ; -- RIGHT OUTER JOIN演算子例文 SELECT * FROM table_1 FULL JOIN table_2 ON table_1.id = table_2.id ;

WHERE句

WHERE句は出力するレコードを条件式を使って指定することができます。SELECT句ではカラムを、WHERE句ではレコードを指定することで欲しいデータを得ることができます。

-- 条件を1つ指定 SELECT * FROM table_1 WHERE name = 'ABC' ; -- 条件を複数指定 SELECT * FROM table_1 WHERE name > 100 AND name < 500 ;

GROUP BY句

GROUP BY句ではSELECT句で指定したデータ対象を同じ値でまとめることができます。まとめると何が良いかというと、1つには指定したデータ対象の重複が無くなりますので、データの種類がよく分かります。

SELECT category FROM table_1 GROUP BY category ; --実は以下クエリでも同じ結果が得られます SELECT DISTINCT category FROM table_1 ;

ただ、重複したレコードをまとめることがGROUP BY句の目的ではありません(何せDISTINCTオプションで代用できるのですから)。GROUP BY句は関数のカテゴリの1つ――集計関数と併用することで各データごとの平均や合計を知るために用いられます。以下のクエリは各カテゴリごとのポイントの平均を求めるクエリです。

SELECT category, AVG(point) FROM table_1 GROUP BY category ;

HAVING句

HAVING句では集計関数によって、まとめられた値を対象に出力するレコードを絞ることができます。やっていること自体はWHERE句と同じですが、こちらは集計関数でまとめられたデータのみに対して使えます。まとめられていないデータに対してHAVING句は使えません。

SELECT category, AVG(point) FROM table_1 GROUP BY category HAVING AVG(point) = 5 ;

ORDER BY句

ORDER BY句では出力した結果の並びを整えることができます。並び変える基準となる対象を指定し、その後ろにASC(昇順)DESC(逆順)を指定します。ASC・DESCを指定しなかった場合、ASCが自動的に適用されます。

SELECT recode_id, update_date, product_price FROM table_1 ORDER BY update_date