Print Friendly, PDF & Email

この記事では、弊社の新人エンジニア研修の参考にMySQLを解説します。

前回はER図からテーブルを作成する方法を解説しました。

今回は、MySQL Workbenchを使ってテーブルを検索する方法を解説します。

検索の基本

SELECT文はテーブルからデータを抽出するための文です。

データベースが何のためにあるのかといえば、それはデータを取り出して活用するためです。

そのため、データベースのDML(Data Manipulation Language)の中でもSELECT文は最重要です。

先に用意した以下のようなテーブルに対してSELECT文を実行してみましょう。

car_table

SELECT文の構文

SELECT 列名1,列名2, ... FROM 表名;

どの表からどんな列を取得するのかという文になっているので直感的にも分かりやすいと思います。

また、この操作はリレーショナル・データベースの3種類の表操作のうち射影(projection)にあたります。

SELECT文の例文

SELECT name, price FROM sip_a.cars;

<結果を表示する>

このようにSQL文の文末にはセミコロン(;)を付けます。

このことはJavaを学んだ新人エンジニアの皆さんですと同じですので馴染みやすいでしょう。

「sip_a.cars」という表記は「スキーマ名.テーブル名」という意味です。

スキーマを選択済みであれば テーブル名だけにして「cars」 と書いても同じことです。

また、以下のようにキーワードの途中でなければ改行を入れて見やすくすることも可能です。

改行を入れて見やすくした例

SELECT
 name, price
FROM
 sip_a.cars;

上記の例はMySQL WorkbenchのBeautify Queryという機能です。

以下のホウキのようなアイコンをクリック、または、ショートカットキー「Ctrl + B」でできますので積極的に活用しましょう。

なお、Javaとは違いSQLは大文字と小文字を区別しません

したがって以下のように書いても同じ結果が得られます。

全て小文字にした例

select
 name, price
from
 sip_a.cars;

しかし、見にくくなりますので「SELECT」、「FROM」といったキーワードは大文字の方が良いでしょう。

また、以下のように2つ目以降の列名の先頭にカンマ( , )をつける書き方を好む人もいます。

この書き方は、最後の列名(下記の end_of_life_dates )の後ろにカンマを付けてしまうミスを防ぐのに役立ちます。

select
 id
 ,name
 ,price
 ,end_of_life_dates
from
 sip_a.cars;

列名等をスペルミスなく入力するにはNetBeansのときと同様に「Ctrl + Space」でコード補完が使ます。

Columnsのところからダブルクリックまたはドラッグ・アンド・ドロップで列名やテーブル名を挿入できることを知っておくと良いでしょう。

列名やテーブル名を挿入できる

コメントを入れてわかりやすくした例

なお、コメントを入れることでSQLを分かりやすく説明することができます。

一行コメントは「--」、複数行コメントはJavaと同じ「/* */」です。

一行コメントのショートカットキーもJavaと同じですので講師に尋ねてください。

最後に、よく使われる*(アスタリスク、英語圏では略称でスターとも呼ばれる)を使って全ての列を指定する方法を見てみます。

*を使って全ての列を指定した例

SELECT
 *
FROM
 sip_a.cars;

結果はご自身で確認ください。

*を使うこの方法は便利ですが、このあとWebアプリケーションを作成する際には問題になることがあります。
なぜなら、列の数や並びはALTER文で変更されることもあるからです。
したがって、SELECTの後にはできるだけ列名を個別に記述すべきです。
ただし、この記事ではそのとき解説している論点を明確にしたいがために *を 使う場面があることを了解ください。

検索の基本の例題

例題1

cars表から、全てのレコードのidとpriceを取得しなさい。

<解答例>

SELECT 
    id
    ,price
FROM
    sip_a.cars;

例題2

cars表から、全てのレコードのnameとend_of_life_datesを取得しなさい。

<解答例>

SELECT 
    name
    ,end_of_life_dates
FROM
    sip_a.cars;

条件付き検索

先のSELECT文では全てのレコードを抽出しました。

WHERE句を使うことでレコードの抽出に条件をつけることができます。

条件付きSELECT文の構文

SELECT 列名1,列名2, ... FROM 表名 WHERE 条件式;

抽出条件はJavaでも学んだ条件式です。

条件式は結果がTRUE又はFALSEに評価できるものでなければならなかったことを思い出してください。

なお、この操作はリレーショナル・データベースの3種類の表操作のうち選択(selection)にあたります。

条件式の書き方

まずは、=を使って条件と等しいレコードを抽出してみます。

数値の場合はそのまま書きます。

SELECT 
    name, end_of_life_dates
FROM
    cars
WHERE
    id = 4;

<結果を表示する>

この時の注意点としてDBMSはテーブル中の全てのレコードに対して条件式の真偽を確かめるということです。

以下のようなイメージです。

文字列や日時の場合はシングルクォート(')で囲みます。

SELECT 
    name, end_of_life_dates
FROM
    cars
WHERE
   name = 'クーペ';

<結果を表示する>

SELECT 
    name, end_of_life_dates
FROM
    cars
WHERE
   end_of_life_dates = '2021-01-01';

<結果を表示する>

算術演算子

Javaと同様の以下の算術演算子が使えます。

算術演算子説明式の例結果(値)
+数値同士の加算SELECT 1 + 23
- 数値同士の減算SELECT 1 - 2-1
* 数値同士の掛け算SELECT 1 * 22
/ 数値同士の割り算SELECT 1 / 2
SELECT 1 / 2.0
SELECT 1.0 / 2
SELECT 1.0 / 2.0
0.5000

Javaと異なる点は、割り算の際、上記4つの式の例はいずれも 0.5000 となるところです。

例えば、以下のSELECT文は、cars表からname,price,price*1.1を税込価格として全てのレコードを抽出します。

SELECT 
    name
    ,price
    ,price * 1.1
FROM
    cars;

<結果を表示する>

なお、以下のようにprice * 1.1は税込価格という別名を付けて表示するとなお分りやすくなります。

SELECT 
    name
    ,price
    ,price * 1.1 as '税込価格'
FROM
    cars;

<結果を表示する>

別名をつける際にはキーワードASを使います。

例題1

cars表から、name、price、price*0.9をセール価格という別名で全てのレコードを取得しなさい。

<解答を見る>

SELECT 
    name
    ,price
    ,price * 0.9 as 'セール価格'
FROM
    cars;

関係(比較)演算子1

Javaと同じように次のような演算子が使えます。

関係演算子説明式の例結果(値)
=左辺と右辺が等しいSELECT 1 == 11 (TRUE)
!=  または <>左辺と右辺が等しくないSELECT 1 != 21 (TRUE)
>左辺が右辺より大きいSELECT 1 > 20 (FALSE)
<左辺が右辺より小さいSELECT 1 < 21 (TRUE)
>=左辺が右辺以上であるSELECT 1 >= 20 (FALSE)
<=左辺が右辺以下であるSELECT 1 <= 21 (TRUE)

注意点としては、等しいがイコール1つであること。(Javaは==でした)

等しくないは、 <> も使えることです。

例えば、以下のSELECT文は、 cars表からpriceが100万円のnameとpriceを抽出します。

SELECT 
    name, price
FROM
    cars
WHERE
    price = 1000000;

<結果を表示する>

例題1

cars表から、idが6以上のnameとpriceを取得しなさい。

<解答を見る>

SELECT 
    name, price
FROM
    cars
WHERE
    id >= 6;

例題2

cars表から、priceが200万未満のidとname、priceを取得しなさい。

<解答を見る>

SELECT 
    id, name, price
FROM
    cars
WHERE
    price < 2000000;

関係(比較)演算子2

ここではJavaには存在しないSQL特有の関係演算子を見ていきます。

関係演算子説明句の例
BETWEEN ~ AND値が値の範囲内に含まれているかどうかを確認しますWHERE price BETWEEN 1000000 AND 2000000;
INある値が値セット内に含まれているかどうかを確認しますWHERE price IN (1980000 , 1390000);
IS NULLNULLであるかどうかを確認しますWHERE end_of_life_dates IS NULL;
LIKE文字列のパターン一致(あいまい検索)をします。WHERE name LIKE '%車';

なお、上記関係演算子には全て頭にNOTをつけることで否定の意味になります。

具体的にはそれぞれ、「NOT BETWEEN ~ AND 」,「NOT IN」 ,「NOT IS NULL」 ,「NOT LIKE」 です。

BETWEEN ~ AND を使ったSELECT文

以下のSELECT文は、cars表からpriceが100万円以上200万円以下のnameとpriceを抽出します。

SELECT 
    id, name, price
FROM
    cars
WHERE
    price BETWEEN 1000000 AND 2000000;

<結果を表示する>

このとき100万の軽自動車が含まれていることに留意ください。

以下のようにNOTを使うとpriceが100万円以上200万円以下でないnameとpriceを抽出します。

SELECT 
    id, name, price
FROM
    cars
WHERE
    price NOT BETWEEN 1000000 AND 2000000;

<結果を表示する>

INを使ったSELECT文

次にINを使ってリストにある場合にデータを抽出する例を見ていきます。

以下のSELECT文は、cars表からpriceが198万円 または 139万円のレコードを抽出します。

SELECT 
    *
FROM
    cars
WHERE
    price IN (1000000 , 1980000);

<結果を表示する>

IS NULLを使ったSELECT文

次に、IS NULLを使って空欄のあるデータだけを抽出してみます。

NULLとは未定義を意味する特別な値です。

数値のゼロ(0)や文字列の空白とは違います。

NULLが存在するメリットとしては、例えば銀行口座を開設したばかりで残高が未定義なのか、それとも0円なのかを区別することができます。

以下のSELECT文は、cars表からend_of_life_datesがNULL、すなわち販売中の車のname,とend_of_life_datesを抽出します。

SELECT 
    name, end_of_life_dates
FROM
    cars
WHERE
    end_of_life_dates IS NULL;

<結果を表示する>

このとき初学者が犯しがちなミスは

WHERE end_of_life_dates = NULL;

としてしまうことです。

NULL値と等しい値はありませんし NULL値との大小比較も無意味です。

例えば、「SELECT NULL = NULL;」という文はNULLが抽出されます。

以下のSELECT文は、cars表からend_of_life_datesがNULLでない、すなわち販売終了している車のname,とend_of_life_datesを抽出します。

SELECT 
    name, end_of_life_dates
FROM
    cars
WHERE
    end_of_life_dates IS NOT NULL;

<結果を表示する>

LIKEを使ったSELECT文

最後にこれも大変利用シーンの多いあいまい検索を解説します。

あいまい検索には以下のワイルドカードを使います。

「%」 :任意の文字列 (ゼロ文字を含む)

「_」 :任意の単一の文字

を意味します。

ワイルドカードとはその名の通りトランプのゲームでジョーカーが他のどのようなカードとも読み替えられることを考えるとイメージしやすいでしょう。

文字列意味該当する例該当しない例
a%「a」から始まる文字列art, autumn, Australia(※)idea
%a%「a」 を含む文字列art, car, idea book
%a「a」 で終わる文字列Australia, ideaart
a_「a」から始まる2文字 ancar
_a_2文字目に「a」がある3文字carart
__a 「a」で終わる3文字 eraart, car

※MySQLのデフォルトでは、英字の大文字と小文字が区別されません。

とくに、 「a」 を含む文字列 として %a% という表現は弊社の新人エンジニア研修でもよく使いますから押さえてください。

以下のSELECT文は、cars表から「車」で終わるレコードを抽出します。

SELECT 
    id, name, price
FROM
    cars
WHERE
    name LIKE '%車';

<結果を表示する>

=ではなくLIKEを使うということも間違えやすいので気をつけましょう。

英語でも「She is like a flower.」のような表現がありましたね。

例題1

cars表から、以下のようにnameに「ー」が含まれるレコードのid、name、priceを取得しなさい。

<解答を見る>

SELECT 
    id, name, price
FROM
    cars
WHERE
    name LIKE '%ー%';

例題2

cars表から、以下のようにend_of_life_datesが2月のレコードのnameとprice、end_of_life_datesを抽出しなさい。

<解答を見る>

SELECT 
    name, price
FROM
    cars
WHERE
    end_of_life_dates LIKE '_____02___';

ワイルドカードの考え方はSQL以外の情報処理の世界でも使われるものです。

新人エンジニアの皆さんは、ぜひ、この機会にマスターしてください。

論理演算子

Java同様、SQLでも論理演算子を使うと複雑な条件式を組み合わせることができます。

SQLの論理演算子はANDとORとNOTです。

NOTはすでに見たのでANDとORについて確認しましょう。

演算子 式がtrueになる条件 使用例Javaの場合(復習)
AND左辺と右辺の両方がtrueWHERE name LIKE '%ン%' AND end_of_life_dates IS NULL;&&
ORすくなくとも左辺と右辺のどちらかがtrueWHERE name LIKE '%ン%' OR end_of_life_dates IS NULL;||

具体例で見てみます。

SELECT 
    name, price, end_of_life_dates
FROM
    cars
WHERE
    name LIKE '%ン%' AND end_of_life_dates IS NULL;

<結果を表示する>

SELECT 
    name, price, end_of_life_dates
FROM
    cars
WHERE
    name LIKE '%ン%' OR end_of_life_dates IS NULL;

<結果を表示する>

一般にAND条件は対象を絞り込むのに対して、OR条件は対象を広げます。

上記例では2つの条件の組み合わせでしたが、3つ以上の条件を組み合わせることもできます。

例題を解いてみましょう。

例題1

cars表から、以下のように販売中でかつpriceに1.1を掛けた値が230万円以上かつnameに「ン」が含まれるレコードのすべての列を抽出しなさい。

<解答を見る>

SELECT 
    *
FROM
    cars
WHERE
    end_of_life_dates IS NULL
        AND price * 1.1 >= 2300000
        AND name LIKE '%ン%'; 

3つ以上の条件をつなげた際、AND条件はOR条件に優先します。

だだし、丸括弧()で優先順位を変えられるのはJavaで学んだとおりです。

今回みたWHERE句を使った条件指定はUPDATE文やDELETE文でも使用します。

SELECT文だけで使うわけではありません。

更新するレコードや削除するレコードを特定するためです。

逆に言えば、 WHERE句のない UPDATE文やDELETE文 は全てのレコードを対象にしますから一般的には殆ど使わないと思っておきましょう。

この点はまた触れていきます。

まとめ

  • SELECT文の作り方3ステップ
1.テーブルを選ぶ
FROM
cars
2.列を選ぶ
SELECT
 name, price, end_of_life_dates

FROM
cars
3.抽出条件を記述する
SELECT
 name, price, end_of_life_dates
FROM
 cars
WHERE
 end_of_life_dates IS NULL
 AND price * 1.1 >= 2300000
 AND name LIKE '%ン%';
  1. Javaに似た関係演算子として、「=, != または<>, >, <, >=, <=」が使用できる
  2. Javaにはない関係演算子として、「BETWEEN ~ AND, IN, IS NULL, LIKE」が使用できる
  3. NULL値と等しい値はなく、NULL値との大小比較も無意味である
  4. 論理演算子は「AND, OR, NOT」である

以上、検索(SELECT文)について見てきました。

次は検索結果のソート、グループ化と集約関数について見ていきましょう。

データベース(MySQL)へ戻る