CodeIQ MAGAZINECodeIQ MAGAZINE

【謎解きプログラム】データベースを扱ってみよう【SQLite】解答と解説

2017.03.10 Category:CodeIQ問題解説・リーダーボード Tag:

  • 1
  • このエントリーをはてなブックマークに追加
entry

言語不問で、プログラムにちなんだ謎を解く「謎解きプログラム」。

あなたは見事、謎を解けましたか? というわけで、出題者の柳井さんによる解答と解説をどうぞ!
by CodeIQ運営事務局

【謎解きプログラム】データベースを扱ってみよう【SQLite】

本問題は、表題のテーマで、プログラムにちなんだ謎を解くというものでした。

それでは以下、各問題とその解答を見ていきましょう。

問題のオープニング

ある日、出社すると、あなたのPCのログイン画面に、謎の挑戦状が表示されていた。

「24時間以内にが解けない場合は、このPCのデータは消失する。

 は、あなたが真のプログラマーなら解けるものだ」

これは挑戦状ではなく脅迫状だ!

そこには、見たことのない謎が掲載されていた。

あなたは歴戦のプログラマーとして、データを救うために、この謎に挑むことになった。

前提条件

問題は、タイトルの通り、SQLiteで実行するものとします。

CodeIQのCoding SandboxでSQLを選ぶと、sqlite3で実行されます。問題やサンプルは、このサンドボックスで実行するものとします。

問題1

以下のテーブルがあるとします。

-- テーブルの作成と、データの追加
create table person(id integer primary key, name text, point integer, address text);
insert into person values(1, 'Tanaka',  90, 'Tokyo');
insert into person values(2, 'Satou',   80, 'Tokyo');
insert into person values(3, 'Honda',   77, 'Chiba');
insert into person values(4, 'Goto',    65, 'Tokyo');
insert into person values(5, 'Suzuki',  23, 'Chiba');
insert into person values(6, 'O''hara', 50, 'Saitama');

-- 表示の設定
.mode column
.headers ON

このテーブルから、pointが60以上の人のデータを抽出して出力するSQL文を選んで下さい。

// 選択肢
select * from where point >= 60;
select * from person where point >= 60;
select * from where upper 60;
select * from person where upper 60;

まずは、どういったテーブルかを確認するために、問題のSQL文を実行したあとに、「select * from person;」でテーブルの中身を出力してみましょう。

select * from person;

id          name        point       address   
----------  ----------  ----------  ----------
1           Tanaka      90          Tokyo     
2           Satou       80          Tokyo     
3           Honda       77          Chiba     
4           Goto        65          Tokyo     
5           Suzuki      23          Chiba     
6           O'hara      50          Saitama   

このテーブルの中から、問題の条件に合致するデータを抽出します。それぞれの選択肢を実行してみましょう。

// 選択肢1
select * from where point >= 60;

(出力は空)
// 選択肢2
select * from person where point >= 60;

id          name        point       address   
----------  ----------  ----------  ----------
1           Tanaka      90          Tokyo     
2           Satou       80          Tokyo     
3           Honda       77          Chiba     
4           Goto        65          Tokyo    
// 選択肢3
select * from where upper 60;

(出力は空)
// 選択肢4
select * from where upper 60;

(出力は空)

「select カラム名 from テーブル名」のように、テーブル名を指定します。また、取得するデータの条件を、WHEREで絞り込む場合は、>=という演算子が利用できます。

というわけで、目的の結果が出力されるのは2番目の選択肢で、「select * from person where point >= 60;」が答えになります。

問題2

以下のテーブルがあるとします。

-- テーブルの作成と、データの追加
create table person(id integer primary key, name text, point integer, address text);
insert into person values(1, 'Tanaka',  90, 'Tokyo');
insert into person values(2, 'Satou',   80, 'Tokyo');
insert into person values(3, 'Honda',   77, 'Chiba');
insert into person values(4, 'Goto',    65, 'Tokyo');
insert into person values(5, 'Suzuki',  23, 'Chiba');
insert into person values(6, 'O''hara', 50, 'Saitama');

-- 表示の設定
.mode column
.headers ON

このテーブルを、pointの高い順に出力するSQL文を選んで下さい。

// 選択肢
select * from person order by point asc;
select * from person order by point unasc;
select * from person order by point desc;
select * from person order by point not asc;

それぞれの選択肢を実行して、結果を見てみましょう。

// 選択肢1
select * from person order by point asc;

id          name        point       address   
----------  ----------  ----------  ----------
5           Suzuki      23          Chiba     
6           O'hara      50          Saitama   
4           Goto        65          Tokyo     
3           Honda       77          Chiba     
2           Satou       80          Tokyo     
1           Tanaka      90          Tokyo     
// 選択肢2
select * from person order by point unasc;

(出力は空)
// 選択肢3
select * from person order by point desc;

id          name        point       address   
----------  ----------  ----------  ----------
1           Tanaka      90          Tokyo     
2           Satou       80          Tokyo     
3           Honda       77          Chiba     
4           Goto        65          Tokyo     
6           O'hara      50          Saitama   
5           Suzuki      23          Chiba     
// 選択肢4
select * from person order by point not asc;

(出力は空)

データをソートする「order by」句は、「asc」が昇順、「desc」が降順です。

というわけで、目的の結果が出力されるのは3番目の選択肢で、「select * from person order by point desc;」が答えになります。

問題3

以下のテーブルがあるとします。

-- テーブルの作成と、データの追加
create table person(id integer primary key, name text, point integer, address text);
insert into person values(1, 'Tanaka',  90, 'Tokyo');
insert into person values(2, 'Satou',   80, 'Tokyo');
insert into person values(3, 'Honda',   77, 'Chiba');
insert into person values(4, 'Goto',    65, 'Tokyo');
insert into person values(5, 'Suzuki',  23, 'Chiba');
insert into person values(6, 'O''hara', 50, 'Saitama');

-- 表示の設定
.mode column
.headers ON

このテーブルの場合において、addressがTokyoのものだけ抽出して出力するSQL文を選んで下さい。

// 選択肢
select * from person where address like 'T*';
select * from person where address glob 'T%';
select * from person where address like 't%';
select * from person where address glob 't*';

それぞれの選択肢を実行して、結果を見てみましょう。

// 選択肢1
select * from person where address like 'T*';

(出力は空)
// 選択肢2
select * from person where address glob 'T%';

(出力は空)
// 選択肢3
select * from person where address like 't%';

id          name        point       address   
----------  ----------  ----------  ----------
1           Tanaka      90          Tokyo     
2           Satou       80          Tokyo     
4           Goto        65          Tokyo    
// 選択肢4
select * from person where address glob 't*';

(出力は空)

データを文字列のパターンで絞り込む「like」や「glob」についての問題です。

「like」では、「%」は任意の0文字以上の文字列です。SQLiteの「like」では、大文字と小文字を区別しません。

「glob」は、Unixでファイルをワイルドカードで指定する書式です。「like」ではないこの方法でも、データを文字列のパターンで絞り込めます。

「glob」では、「*」は任意の0文字以上の文字列です。「glob」では、大文字と小文字を区別します。

というわけで、目的の結果が出力されるのは3番目の選択肢で、「select * from person where address like ‘t%’;」が答えになります。

CodeIQ運営事務局より

柳井さん、ありがとうございました!
現在、柳井さんの最新問題が出題中です。
ぜひ挑戦してみてくださいね!

  • 1
  • このエントリーをはてなブックマークに追加

■関連記事

【コードミステリ】数字に隠されたメッセージ【言語不問】解答と解説... 【コードミステリ】数字に隠されたメッセージ【言語不問】 本問題は、表題のテーマで、簡単なプログラムを書くものです。 喜屋武ちあきさんによるCodeIQ MAGAZINEでのブックレビューに合わせて、『顔貌売人』(文藝春秋)とのコラボ問題として出題されたものです。 それでは以下、問題とその解...
数学の問題をプログラミングで解こう!「ディバイド・アウト」問題解説... 問題のおさらい 自然数 n と素数 p に対し、n の階乗(n!)を p でこれ以上割り切れなくなるまで繰り返し割り、その商をさらに p で割ったときの余りを F(n, p) と定義します。 例えば F(12, 5)=4 です。 12!(=479001600)は 5 で最大 2 回割ることができ...
【息抜き】ファイル名を作ろう【言語不問】解答と解説... 【息抜き】ファイル名を作ろう【言語不問】 本問題は、表題のテーマで、簡単なプログラムを書くものです。 それでは以下、問題とその解答を見ていきましょう。 問題 ファイルをディレクトリ内に作成する際、同じ名前のファイルがあると、末尾に数字を付けるなどして同じ名前にならないようにします。 こうし...
【夏のミステリー】殺人現場のコード 解答と解説... 【夏のミステリー】殺人現場のコード 本問題は、表題のテーマで、簡単なプログラムを書くものです。 それでは以下、問題とその解答を見ていきましょう。 問題 殺人現場にプログラマが倒れていて、途中までプログラムが書かれている。 「続きを書いて欲しい」 これはダイイングメッセージなのか? どう...
数学の問題をプログラミングで解こう!「キャンディ・アンド・チョコレート」問題解説... 問題のおさらい n 個のキャンディをグループに分けます。 グループの最大のキャンディの個数が k 個となるような分け方の数を F(n, k) と定義します。 例えば、F(8, 3)=5 です。このときの分け方を以下に示します。 なお個々のキャンディを区別せずに扱う点に注意してください。 同...
【夏のミステリー】時間制限の密室 解答と解説... 【夏のミステリー】時間制限の密室 本問題は、表題のテーマで、簡単なプログラムを書くものです。 それでは以下、問題とその解答を見ていきましょう。 問題 (なんやかんやあって)命からがら逃げてきた、あなた。 しかし逃げ込んだ部屋にあなたが入った途端、自動でドアはロックされ、しかも10分後にはガ...

今週のPickUPレポート

新着記事

週間ランキング

CodeIQとは

CodeIQ(コードアイキュー)とは、自分の実力を知りたいITエンジニア向けの、実務スキル評価サービスです。

CodeIQご利用にあたって
関連サイト
codeiq

リクルートグループサイトへ