並べ替え

ORDER BY

SELECT文で検索した検索結果は、並べ替えることができます。並べ替えを行うには、ORDER BYを行います。書式は以下の通りになります。

SELECT <列名1> [, 列名2 ...] FROM <テーブル名> [WHERE条件式など]
ORDER BY <列名1> [ASC, DESC] [, 列名2[ASC, DESC] ...]

並べ替え順序は、ASC,DESC、もしくは省略をすることができます。ASCは昇順(しょうじゅん)、DESCは降順(こうじゅん)で、省略した場合はASCとなります。昇順とは、小さい順<、降順とは、大きい順に並べ替えることです。

ASCとDESC

実際のテーブルを使って試してみましょう。テーブルは4日目resourceテーブルを用いることにします。値段(price)での昇順の並べ替えをする、以下のSQL文を実行してみましょう。

Sample501.sql(昇順の並べ替え)
SELECT * FROM resource ORDER BY price ASC;

実行結果は以下の通りになります。

図5-1.resourceテーブルのpriceによる昇順の並べ替え
昇順の並べ替え

resourceテーブルが、priceが小さい順から並べられていることがわかります。なお、昇順の並べ替えの場合は、ASCは省略可能です。

Sample502.sql(昇順の並べ替え:ASC省略)
SELECT * FROM resource ORDER BY price;

続いて、降順の並べ替えを見てみることにしましょう。

Sample503.sql
SELECT * FROM resource ORDER BY price DESC;

実行結果は以下の通りになります。

図5-2.resourceテーブルのpriceによる降順の並べ替え
降順の並べ替え

今度は、priceが高い順から並べ替えられていることがわかります。

複数のデータの並び変え

並び変えができるのは、単独のカラムのデータだけではありません。複数の行になわたって並べ替えをすることができます。その結果を確認するために、まず以下のsqlを実行し、新しいテーブルscoreを生成して、そこにデータを入れてください。

Sample504.sql(scoreテーブルの生成とデータの挿入)
CREATE TABLE score
(
    id                          INT NOT NULL,
    math                        INT NOT NULL,
    english                     INT NOT NULL,
    science                     INT NOT NULL
);

INSERT INTO score ( id, math, english, science ) VALUES (1001,90,80,95);
INSERT INTO score ( id, math, english, science ) VALUES (2001,52,60,100);
INSERT INTO score ( id, math, english, science ) VALUES (3001,76,98,64);
INSERT INTO score ( id, math, english, science ) VALUES (3002,30,20,45);

このテーブルのデータは、学生のidと、数学(math)、英語(english)、理科(science)のテストの結果を対応させるものです。その結果得られるテーブルは、以下のようになります。(図5-3.)

図5-3.scoreテーブルの内容
scoreテーブルの内容

これを、科目ごとに並べ替えてみましょう。まずは、数学を降順、英語を昇順で並べ替えてみましょう。(図5-4.)

Sample506.sql(scoreテーブルの生成とデータの挿入)
SELECT * FROM score ORDER BY math DESC,english ASC;
図5-4.数学を降順、英語を昇順で並べ替え
数学を降順、英語を昇順で並べ替え

続いて、以下のSQLを実行してみましょう。今度は、理科を昇順、英語を降順で並べ替えています。(図5-5.)

Sample506.sql(scoreテーブルの生成とデータの挿入)
SELECT * FROM score ORDER BY science ASC,english DESC;
図5-5.理科を昇順、英語を降順で並べ替え
理科を昇順、英語を降順で並べ替え

このように、複数のカラムに並べ替え条件を指定すると、先頭にあるものを優先した並べ替えを行います。

集約

GROUP BY

SQLで、列の値を集計する場合、集計はグループ単位で行われます。グループとは特定のカラムに格納されている同じ値を持つデータをまとめたもので、どの列を対象にグループ化するのかを指定するにはGROUP BY句を使用します。書式は次の通りです。

配列の長さ
SELECT 列名, ... FROM テーブル名GROUP BY列名, ...;

GROUP BY句の後に列名を指定すると、そのカラム名に格納されている値が同じデータをグループとしてまとめます。

複数カラムを指定した場合、複数のカラムの値の組み合わせが同じデータをグループとしてまとめます。

グループ化するとSELECT文で取得できるデータの数はグループの数だけとなります。そこでグループ化を行った場合には、グループ化に指定したカラムの値や、用意された関数を使ってカラムの値をグループ単位で集計した結果などを取得することができます。

例えば、次のような、重複するデータが存在する検索結果があったとします。

Sample505.sql
SELECT class FROM resource;

この実行結果は、以下のようになります。(図5-6.)

図5-6.resourceテーブルのclass列の表示
resourceテーブルのclass列の表示

見てわかるとおり、「text」や「sftw」などといった項目が複数あることがわかります。これを、GROUP BYによって集約します。

Sample506.sql
SELECT class FROM resource GROUP BY class;

すると、今後の実行結果は、以下のようになります。(図5-7.)

図5-7.resourceテーブルのclassの集約
resourceテーブルのclassの集約

実行結果からわかるように、名前の重複が回避されたことがわかります。重複する値が、GROUP BYにより、一つに集約された結果です。(図5-8.)

図5-8.classの集約のイメージ
classの集約のイメージ

なお、このような重複の回避は、GROUP BYだけではなく、distinctを用いることでも実現できます。

Sample507.sql
SELECT distinct class FROM resource;

GROUP BYによる表現ばかりでなく、こちらの表現も覚えておくとよいでしょう。

集計処理

集計と関数

GROUP BYを使う利点は、重複の回避だけではありません。合計値や、平均値の算出などといった、集計処理にも利用できます。書式は以下の通りになります。

集計処理
SELECT 列名, ... ,集計関数(集計をとる列名)FROM テーブル名GROUP BY列名, ...;

では、実際の例で説明してみましょう。今、以下のようなテーブルがあったとします。再び、resourceテーブルで、以下の通りの検索を行ってみてください。

Sample508.sql
SELECT class,AVG(price) FROM resource GROUP BY class;

すると、今後の実行結果は、以下のようになります。(図5-9.)

図5-9.resourceテーブルのclassごとのpriceの平均
resourceテーブルのclassごとのpriceの平均

このSQL文では、resourceテーブルをclassでグループ化し、平均値をとっています。AVGは、平均値をとる集計関数です。(図5-10.)

図5-10.AVG関数の作用のイメージ
AVG関数の作用のイメージ

なお、GROUP BYで用いられる集計関数には、以下のようなものがあります。(表5-1.)

表5-1.集計関数
関数名意味
MAX最大値
MIN最小値
SUM合計
AVG平均
COUNT個数のカウント

集計処理における条件

集計処理には、条件を付けることも可能です。その際使用するのが、HAVING句です。使用方法は以下の通りです。

HAVING句
SELECT 列名, ... ,集計関数(集計をとる列名)FROM テーブル名GROUP BY列名, ... HAVING 条件式;

では、実際に前述のresourceテーブルで、実際に試してみましょう。

Sample509.sql
SELECT class,AVG(price) FROM resource GROUP BY class HAVING count(class) >= 2;

すると、実行結果は、以下のようになります。(図5-11.)

図5-11.HAVINGによる条件付け
HAVINGによる条件付け

COUNT関数は、同じ要素が出る数値を数えるものです。例えば、textは3つありますから、このグループのCOUNTの値は3、mdvdは1つしかないので、値は1…、といった具合になります。(図5-12.)

図5-12.COUNT関数の作用のイメージ
COUNT関数の作用のイメージ

このことから、classの出現回数が2回以上のもの、という条件になることから、一回しか名前の出現しない列は選択されないため、図5-11.のような結果になります。