データ検索の基本
構文
SELECT 列名1 [ AS 別名1 ] [ ,列名2 [ AS 別名2 ] …]
FROM 表名
[ WHERE 検索条件 ];

説明
SELECT〜は表からデータの検索を行う。列名に「*」を指定することで全ての列が表示される。
また列名 AS 別名で検索結果の列見出しを変更できる。(ASは省略可)
WHEREを付加することで条件と一致する特定の行を取り出すこともできる。
顧客表を表示する。

db=# select * from customer ;
 no  |        name        | age |    job    |    date    |      mail      | contno
-----+--------------------+-----+-----------+------------+----------------+--------
 101 | Taro Tanaka        |  23 | Finance   | 1998-02-20 | taro@example.co.jp     |      1
 102 | Kenji Hayashi      |  43 | Bank      | 1998-03-12 | kenji@example.co.jp    |      1
 103 | Yasuyuki Morishita |  19 | Student   | 1998-04-11 | yasuyuki@example.co.jp |      2
 104 | Tomoyuki Nakajima  |  32 | Bank      | 1998-05-18 | tomoyuki@example.co.jp |      5
 105 | Takao Takahashi    |  36 | Transport | 1998-06-09 | takao@example.co.jp    |      3
 107 | Masashi Ito        |  26 |           | 1998-06-09 | masashi@example.co.jp  |      4
 108 | Masaru Oohashi     |  46 | Finance   | 1998-11-19 | masaru@example.co.jp   |      3
 109 | Tomoko Kawaguchi   |  24 |           | 1998-12-04 | tomoko@example.co.jp   |      2
 110 | Aki Suzuki         |  18 | Student   | 1998-12-26 | aki@example.co.jp      |      3
(9 rows)
顧客表から年齢が30歳以上である顧客の顧客名と年齢を表示する。(列の見出しに別名をつける。)

db=# select name, age from customer
db-# where age > 29;
       name        | age
-------------------+-----
 Kenji Hayashi     |  43
 Tomoyuki Nakajima |  32
 Takao Takahashi   |  36
 Masaru Oohashi    |  46
(4 rows)
検索結果の重複行を1つにまとめる(DISTINCT)
構文
SELECT DISTINCT 列名1 [ ,列名2 …]
FROM 表名
[ WHERE 検索条件 ];

説明
DISTINCTを付加することで検索結果の重複している行を排除することができる。(1つにまとめる)

顧客表から顧客の仕事を全て表示する。

db=# select job from customer;
    job
-----------
 Finance
 Bank
 Student
 Bank
 Transport

 Finance

 Student
(9 rows)
顧客表から顧客の仕事を全て表示する。(重複行の排除)

db=# select distinct job from customer;
    job
-----------

 Bank
 Finance
 Student
 Transport
(5 rows)
検索結果の重複行を1つにまとめる(DISTINCT ON)
構文
SELECT DISTINCT ON (列名1 [ ,列名2 …]) 列名1 [ ,列名2 …]
FROM 表名
[ WHERE 検索条件 ];

説明
DISTINCTは選択する列の組み合わせを対象に重複を判断するが、DISTINCT ONは重複の対象にする列を指定できます。
またDISTINCT ONで指定した列はORDER BY句を使用する場合、ORDER BY句で最初に指定しなければならない。

顧客表から顧客の仕事と地域番号を表示する。(顧客の仕事と地域番号の組み合わせで重複を判断している。)

db=# select distinct job, contno from customer;
    job    | contno
-----------+--------
           |      2
           |      4
 Bank      |      1
 Bank      |      5
 Finance   |      1
 Finance   |      3
 Student   |      2
 Student   |      3
 Transport |      3
(9 rows)
顧客表から顧客の仕事と地域番号を表示する。(顧客の仕事で重複を判断している。)

db=# select distinct on (job) job, contno from customer;
    job    | contno
-----------+--------
           |      4
 Bank      |      1
 Finance   |      1
 Student   |      2
 Transport |      3
(5 rows)
上記例では顧客の仕事で重複を判断し、地域番号は最初に現れたものが選択される。
地域番号が大きいものを選択したいのであればGROUP BY句を使用する。

db=# select distinct on (job) job, max(contno) from customer group by job;
    job    | max
-----------+-----
           |   4
 Bank      |   5
 Finance   |   3
 Student   |   3
 Transport |   3
(5 rows)
複数の検索条件を指定する(AND、OR)
構文
SELECT 列名1 [ ,列名2 …]
FROM 表名
WHERE 検索条件1 論理演算子 検索条件2;

説明
検索条件を複数指定したい場合は論理演算子で条件を繋ぎます。ANDは検索条件1と検索条件2をどちらも満たす ことを意味し、ORは検索条件1と検索条件2のどちらかを満たすことを意味します。論理演算子には優先順位があり、 NOT、AND、ORの順番に評価されるので優先順位を変えたい場合は()を利用します。()で囲まれた条件がはじめに評価されます。

顧客表から登録日が98年の5月以降で、かつ年齢が20代である顧客の顧客名を表示する。

db=# select name from customer
db-# where ( date >= '1998-05-01' ) and ( age >= 20 ) and ( age < 30 );
       name
------------------
 Masashi Ito
 Tomoko Kawaguchi
(2 rows)
顧客表から職業が金融または銀行で、かつ年齢が40歳以上である顧客の顧客名を表示する。

db=# select name from customer
db-# where age >= 40 and ( job = 'Finance' or job = 'Bank' );
      name
----------------
 Kenji Hayashi
 Masaru Oohashi
(2 rows)
検索条件に値の下限、上限を指定する(BETWEEN)
構文
SELECT 列名1 [ ,列名2 …]
FROM 表名
WHERE 列名 BETWEEN 下限値 AND 上限値;

説明
列の値がある範囲に存在する場合の検索条件としてBETWEENを使用できます。これは下限値以上で上限値以下のデータが 該当します。(下限値 ≦ データ ≦ 上限値)

顧客表から年齢が20〜40歳である顧客の顧客名、年齢、登録日を表示する。(BETWEENを使用)

db=# select name, age, date from customer
db-# where age between 20 and 40;
       name        | age |    date
-------------------+-----+------------
 Taro Tanaka       |  23 | 1998-02-20
 Tomoyuki Nakajima |  32 | 1998-05-18
 Takao Takahashi   |  36 | 1998-06-09
 Masashi Ito       |  26 | 1998-06-09
 Tomoko Kawaguchi  |  24 | 1998-12-04
(5 rows)
顧客表から年齢が20歳以上で40歳以下である顧客の顧客名、年齢、登録日を表示する。

db=# select name, age, date from customer
db-# where ( age >= 20 ) and ( age <= 40 );
       name        | age |    date
-------------------+-----+------------
 Taro Tanaka       |  23 | 1998-02-20
 Tomoyuki Nakajima |  32 | 1998-05-18
 Takao Takahashi   |  36 | 1998-06-09
 Masashi Ito       |  26 | 1998-06-09
 Tomoko Kawaguchi  |  24 | 1998-12-04
(5 rows)
検索条件に複数の値の候補を指定する(IN)
構文(IN)
SELECT 列名1 [ ,列名2 …]
FROM 表名
WHERE 列名 IN ( 値1 [ ,値2 …] );

説明
列の値が複数の候補のいずれかと一致する場合の検索条件としてINを使用できます。()内に値の候補を記述します。 この候補のいずれかと一致したものが該当します。

顧客表から職業が銀行または運送または金融である顧客の顧客名を表示する。(INを使用する)

db=# select name from customer
db-# where job in ('Bank','Transport','Finance');
       name
-------------------
 Taro Tanaka
 Kenji Hayashi
 Tomoyuki Nakajima
 Takao Takahashi
 Masaru Oohashi
(5 rows)
顧客表から職業が銀行または運送または金融である顧客の顧客名を表示する。

db=# select name from customer
db-# where ( job = 'Bank' ) or ( job = 'Transport' ) or ( job = 'Finance');
       name
-------------------
 Taro Tanaka
 Kenji Hayashi
 Tomoyuki Nakajima
 Takao Takahashi
 Masaru Oohashi
(5 rows)
NULLの検索(IS NULL)
構文
SELECT 列名1 [ ,列名2 …]
FROM 表名
WHERE 列名 IS NULL;

説明
NULLは0でも空白でもない値が空の状態であり、この空のデータを検索条件にする場合はIS NULLを使用します。

顧客表から職業のデータを登録していない顧客の顧客名を表示する。

db=# select name from customer
db-# where job is null;
       name
------------------
 Masashi Ito
 Tomoko Kawaguchi
(2 rows)
検索条件にワイルドカードを使用する(LIKE、ILIKE)
構文(LIKE)
SELECT 列名1 [ ,列名2 …]
FROM 表名
WHERE 列名 LIKE 検索パターン
[ ESCAPE ’エスケープ文字’];

構文(ILIKE)
SELECT 列名1 [ ,列名2 …]
FROM 表名
WHERE 列名 ILIKE 検索パターン
[ ESCAPE ’エスケープ文字’];

説明
ワイルドカードは任意の文字に置き換えることができます。ワイルドカードには次のようなものが使用できます。

ワイルドカード説明
_ 任意の1文字。
% 0文字以上の任意の文字。

LIKEは大文字、小文字を区別しますが、ILIKEは区別しません。ですので、LIKEでは’a’と’A’はマッチしませんがILIKEではマッチします。 また、「%」や「_」が含まれる文字列をワイルドカードで検索したい場合は「%」や「_」を通常文字とするために エスケープ文字を指定します。例えば文字列の中に「%」が含まれるデータを検索する場合、

db=# select var from test
db-# where var like '%#%%' escape '#';
       var
------------------
 %abc
 a%bc
 abc%
(3 rows)
となります。
またLIKEは ~~ 演算子とILIKEは ~~* 演算子と同じです。

顧客表からメールアドレスのドメイン名(@以降)がa.comである顧客の顧客名とメールアドレスを表示する。

db=# select name, mail from customer
db-# where mail like '%@example.co.jp';
       name        |      mail
-------------------+----------------
 Taro Tanaka       | taro@example.co.jp
 Tomoyuki Nakajima | tomoyuki@example.co.jp
 Takao Takahashi   | takao@example.co.jp
 Aki Suzuki        | aki@example.co.jp
(4 rows)

db=# select name, mail from customer
db-# where mail ~~ '%@example.co.jp';
       name        |      mail
-------------------+----------------
 Taro Tanaka       | taro@example.co.jp
 Tomoyuki Nakajima | tomoyuki@example.co.jp
 Takao Takahashi   | takao@example.co.jp
 Aki Suzuki        | aki@example.co.jp
(4 rows)
顧客表から顧客名がTから始まる顧客の顧客名を表示する。

db=# select name from customer
db-# where name like 't%';
 name
------
(0 rows)
顧客表から顧客名がTから始まる顧客の顧客名を表示する。

db=# select name from customer
db-# where name ilike 't%';
       name
-------------------
 Taro Tanaka
 Tomoyuki Nakajima
 Takao Takahashi
 Tomoko Kawaguchi
(4 rows)
検索条件にワイルドカードを使用する(SIMILAR TO)
構文
SELECT 列名1 [ ,列名2 …]
FROM 表名
WHERE 列名 SIMILAR TO 検索パターン
[ ESCAPE ’エスケープ文字’];

説明
動作はLIKEとほぼ同じですが、ワイルドカードには次のようなものが使用できます。

ワイルドカード説明
_ 任意の1文字。
% 0文字以上の任意の文字。
+ 直前文字の1回以上の繰り返し。
* 直前文字の0回以上の繰り返し。
() 1つのグループに分ける。
| 二者択一

SIMILAR TOは大文字、小文字を区別します。
また、ワイルドカードが含まれる文字列をワイルドカードで検索したい場合は「%」や「_」を通常文字とするために エスケープ文字を指定します。例えば文字列の中に「+」が含まれるデータを検索する場合、

db=# select var from test
db-# where var similar to '%#+%' escape '#';
       var
------------------
 +abc
 a+bc
 abc+
(3 rows)
となります。

顧客表からメールアドレスのドメイン名(@以降)がa.comである顧客の顧客名とメールアドレスを表示する。

db=# select name, mail from customer
db-# where mail similar to '%@example.co.jp';
       name        |      mail
-------------------+----------------
 Taro Tanaka       | taro@example.co.jp
 Tomoyuki Nakajima | tomoyuki@example.co.jp
 Takao Takahashi   | takao@example.co.jp
 Aki Suzuki        | aki@example.co.jp
(4 rows)
否定条件(NOT)
構文
SELECT 列名1 [ ,列名2 …]
FROM 表名
WHERE NOT 検索条件;

構文(BETWEEN)
SELECT 列名1 [ ,列名2 …]
FROM 表名
WHERE 列名 NOT BETWEEN 下限値 AND 上限値;

構文(IN)
SELECT 列名1 [ ,列名2 …]
FROM 表名
WHERE 列名 NOT IN ( 値1 [ ,値2 …] );

構文(LIKE)
SELECT 列名1 [ ,列名2 …]
FROM 表名
WHERE 列名 NOT LIKE 検索パターン
[ ESCAPE ’エスケープ文字’ ];

構文(ILIKE)
SELECT 列名1 [ ,列名2 …]
FROM 表名
WHERE 列名 NOT ILIKE 検索パターン
[ ESCAPE ’エスケープ文字’ ];

構文(IS NULL)
SELECT 列名1 [ ,列名2 …]
FROM 表名
WHERE 列名 IS NOT NULL;

説明
NOTは否定を意味し、検索条件は逆の意味になります。BETWEENでは「値が下限値から上限値の範囲にないもの」、INでは 「値が複数の候補のいずれとも一致しないもの」、LIKE、ILIKEでは「値が検索パターンと一致しないもの」、IS NULLでは 「値がNULLでないもの」となります。
またNOT LIKEは !~~ 演算子とNOT ILIKEは !~~* 演算子と同じです。

顧客表から年齢が10〜30歳でない顧客の顧客名を表示する。

db=# select name from customer
db-# where age not between 10 and 30;
       name
-------------------
 Kenji Hayashi
 Tomoyuki Nakajima
 Takao Takahashi
 Masaru Oohashi
(4 rows)

顧客表から職業が銀行または金融でない顧客の顧客名を表示する。

db=# select name from customer
db-# where job NOT IN ('Bank','Finance');
        name
--------------------
 Yasuyuki Morishita
 Takao Takahashi
 Aki Suzuki
(3 rows)

顧客表から職業のデータを登録している顧客を表示する。

db=# select name from customer
db-# where job is not null;
        name
--------------------
 Taro Tanaka
 Kenji Hayashi
 Yasuyuki Morishita
 Tomoyuki Nakajima
 Takao Takahashi
 Masaru Oohashi
 Aki Suzuki
(7 rows)
検索結果をソートする(ORDER BY)
構文
SELECT 列名1 [ ,列名2 …]
FROM 表名
[ WHERE 検索条件 ]
ORDER BY 列名1 [ ,列名2 …] [ DESC ] [ ,列名1 [ ,列名2 …] [ DESC ] ];

説明
検索結果をソートするにはORDER BYを使用します。昇順にソートする場合は「ASC」(デフォルトなので省略可)、 降順にソートする場合は「DESC」を指定します。またソート対象列の指定には列名以外に、列の別名やSELECTで指定した 列の番号(先頭から1,2,3…)を指定することもできます。
ORDER BYで指定されたソート対象列は指定順にソートされる。したがって「ORDER BY COL1,COL2 DESC,COL3;」と 指定された場合はまずCOL1の昇順にソートされ、さらにCOL1の値が同じであるデータをCOL2の降順にソートし、 さらにCOL2の値も同じであるデータをCOL3の昇順にソートする。

顧客表を年齢の降順、顧客名の昇順にソートして表示する。

db=# select * from customer
db-# order by age desc, name;
 no  |        name        | age |    job    |    date    |      mail      | contno
-----+--------------------+-----+-----------+------------+----------------+--------
 108 | Masaru Oohashi     |  46 | Finance   | 1998-11-19 | masaru@example.co.jp   |      3
 102 | Kenji Hayashi      |  43 | Bank      | 1998-03-12 | kenji@example.co.jp    |      1
 105 | Takao Takahashi    |  36 | Transport | 1998-06-09 | takao@example.co.jp    |      3
 104 | Tomoyuki Nakajima  |  32 | Bank      | 1998-05-18 | tomoyuki@example.co.jp |      5
 107 | Masashi Ito        |  26 |           | 1998-06-09 | masashi@example.co.jp  |      4
 109 | Tomoko Kawaguchi   |  24 |           | 1998-12-04 | tomoko@example.co.jp   |      2
 101 | Taro Tanaka        |  23 | Finance   | 1998-02-20 | taro@example.co.jp     |      1
 103 | Yasuyuki Morishita |  19 | Student   | 1998-04-11 | yasuyuki@example.co.jp |      2
 110 | Aki Suzuki         |  18 | Student   | 1998-12-26 | aki@example.co.jp      |      3
(9 rows)
顧客表から登録日が98年4月以降の顧客の顧客名、登録日を登録日の降順、顧客名の昇順にソートして表示する。

db=# select name, date from customer
db-# where date >= '1998-04-01'
db-# order by 2 desc, 1;
        name        |    date
--------------------+------------
 Aki Suzuki         | 1998-12-26
 Tomoko Kawaguchi   | 1998-12-04
 Masaru Oohashi     | 1998-11-19
 Masashi Ito        | 1998-06-09
 Takao Takahashi    | 1998-06-09
 Tomoyuki Nakajima  | 1998-05-18
 Yasuyuki Morishita | 1998-04-11
(7 rows)
顧客表から登録日が98年4月以降の顧客の顧客名、登録日を登録日の降順、年齢の降順にソートして表示する。

db=# select name, date from customer
db-# where date >= '1998-04-01'
db-# order by 2, age desc;
        name        |    date
--------------------+------------
 Yasuyuki Morishita | 1998-04-11
 Tomoyuki Nakajima  | 1998-05-18
 Takao Takahashi    | 1998-06-09
 Masashi Ito        | 1998-06-09
 Masaru Oohashi     | 1998-11-19
 Tomoko Kawaguchi   | 1998-12-04
 Aki Suzuki         | 1998-12-26
(7 rows)
グループ分けをする(GROUP BY)
構文
SELECT 列名1 [ ,列名2 …]
FROM 表名
[ WHERE 検索条件 ]
GROUP BY 列名1 [ ,列名2 …];

説明
表全体をまとめて計算し、1行だけ結果を返すグループ関数をSELECTで指定した 場合は列を同時に表示することはできません。
(グループ関数は1行だけ返すが、列は複数行返すため)
そこで列でグループ化することでグループ関数と列を同時に表示できるようになります。よってGROUP BY句で指定されていない列 をSELECT句で指定することはできません。

顧客表から地域番号と地域ごとの顧客数を表示する。

db=# select contno, count(*) from customer;
ERROR:  column "customer.contno" must appear in the GROUP BY clause or be used in an aggregate function

db=# select contno, count(*) from customer
db-# group by contno;
 contno | count
--------+-------
      5 |     1
      4 |     1
      3 |     3
      2 |     2
      1 |     2
(5 rows)
グループ分けをしたデータにさらに検索条件を付加する(HAVING)
構文
SELECT 列名1 [ ,列名2 …]
FROM 表名
[ WHERE 検索条件 ]
GROUP BY 列名1 [ ,列名2…]
HAVING 検索条件;

説明
GROUP BYでグループ化したデータを対象にして、さらに検索条件をつけたい場合はHAVINGを使用します。よって HAVINGを使用する場合は必ずGROUP BYでグループ化している必要があります。

顧客表から地域番号と地域ごとの顧客数が2人以上であるデータを表示する。

db=# select contno, count(*) from customer
db-# group by contno
db-# having count(*) >= 2;
 contno | count
--------+-------
      3 |     3
      2 |     2
      1 |     2
(3 rows)