専門学校30日目(情報工学)5月24日(金)

1時限~3時限
C言語基礎 やさしいC 第5版

先週解いた章末問題の解説がありました。変数がわかりやすいように、int型なら頭にiを付ける、double型ならdを付けるなど工夫をしてほしいとのこと。
scanf_s("%lf", &n);のキーボードからの入力を受け付けるためのコードに"%lf\n"や"%d\n"として改行をいれてしまうと思わぬエラーがでてしまう。ここは気を付けましょう。
printf("三角形の面積は%fです。\n", (teihen * takasa)/ 2);はキャスト演算子を置かずとも2を2.0とするだけで浮動小数点型にできる。
最後の問題は5科目だと5つの変数を用意して計算するのはたやすいが生徒が1000人など多くなると、後の章で学ぶループなどを使った書き方のほうがいいでしょう。

p.114- 第5章
条件分岐は条件式が真か偽かで決まります。その真偽を決める式は関係演算子によります。
==、!=、>、>=、<、<=の演算子があります。

5 > 3 は真
5 < 3 は偽
a == 6 と
a != 6 はaの値で真偽が決まる
内部的には真は1、偽は0という整数値で評価されています。

条件の値に応じて処理を行う文を条件判断文という。その一つとしてif文があります。

#include <stdio.h>
int main(void)
{

int n;
printf("整数を入力してください。\n");
scanf_s("%d", &n);
if (n != 5) {
    printf("入力されたのは");
    printf("5ではありません。\n");
}
printf("処理を終了します。\n");

return 0;
}

ifの条件式は
if (n != 5) {
printf("入力されたのは");
printf("5ではありません。\n");
}
となっていますが、if (n != 5)の後ろにセミコロンはつけません。ここではあえて2行使ってprintf関数を使っています。1行にまとめてもよいです。

条件が偽の場合に指定した分を処理する構文がif else文
if (条件)
文1;
else
文2;

elseを使って70点以上なら合格、そうでなければ不合格と出力するプログラムを作りました。

#include <stdio.h>
int main(void)
{
int itensuu;
printf("点数を入力してください。\n");
scanf_s("%d", &itensuu);
if (itensuu >= 70) {
    printf("合格です。\n");
}else {
    printf("不合格です。\n");
}
return 0;
}

ここでは条件がifとelseの2つでした。今度はもっと多くの条件で実行したい場合にはif~else if~elseを使う。

#include <stdio.h>
int main(void)
{
int itensuu;
printf("点数を入力してください。\n");
scanf_s("%d", &itensuu);
if (itensuu >= 90) {
    printf("優秀です。\n");
}else if (itensuu >= 70) {
    printf("合格です。\n");
}else {
    printf("不合格です。\n");
}
return 0;
}

ここで条件の順番が重要になってくる。90点以上、70点以上、それ以外の順に並んでいますが、70点以上を90点以上より先に書いてしまうと90点以上の場合の文が70点以上の文と同じ出力になってしまう。

もっと多くの条件があった場合、例えば1から100までの分岐処理をしたい場合はどうするのだろう。そのような場合はswitch文を使うとよい。
教科書p.133- switch文
switchは波括弧で囲い、case 1、case 2などで分岐し、分岐の終わりまでが一つのブロックになる。どのcaseにも当てはまらない場合、defaultを入れその処理文を書く。

#include <stdio.h>
int main(void)
{
int itensuu;
printf("点数を入力してください。\n");
scanf_s("%d", &itensuu);
switch (itensuu) {
case 1:
    printf("1が入力されました。\n");
    break;
case 2:
    printf("2が入力されました。\n");
    break;
default:
    printf("1か2を入力してください。\n");
    break;
}
return 0;
}

次にサイコロの出目で異なる文を出力させるプログラムを作りました。1、3、5ならマスを進め、それ以外は1回休みになるものです。

#include <stdio.h>
int main(void)
{
int isaikoro;
printf("サイコロの目を入力してください。\n");
scanf_s("%d", &isaikoro);
switch (isaikoro) {
case 1:
    printf("1コマ進め\n");
    break;
case 3:
    printf("2コマ進め\n");
    break;
case 5:
    printf("3コマ進め\n");
    break;
default:
    printf("1回休み\n");
    break;
}
return 0;
}

p.138-論理演算子
条件をさらに評価して真か偽を得る演算。
(成績が優)&&(お金がある)で二つの条件が真であるときに全体を真とします。AかつBの演算子。
または、を意味する演算子は||です。バーティカルラインはshift+\マークキーで出力されます。
偽であるときに真となるのは!を使います。

5>3 && 3==4は偽
a==6 || a>=12はaが6か12以上で真
!(a==6)はaが6でないときに真となります

次回で5章を終え、中間テストを1章から5章までの範囲とします。


4時限~6時限
webDBシステム開発 スッキリわかるSQL入門第3版ドリル256問付き

p.130-131 章末まとめのSQL文を打ち込んで試しました。

select distinct 費目 from 家計簿

select * from 家計簿
where 日付 >= '2024-03-01'
and 日付 <= '2024-03-31'
order by 出金額 desc

select * from 家計簿アーカイブ
where 費目 = '給料'
order by 入金額 desc
offset 0 row
sfetch next 5 rows only

select * from 家計簿
union
select * from 家計簿アーカイブ
where 費目 = '給料'
and 日付 <= '2024-02-28'
order by 1

select 費目 from 家計簿
except
select 費目 from 家計簿アーカイブ

中間試験の範囲は(第一部の)4章までとなります。

問題を解きましたので解答のSQL文を載せます。

create table 水族館一覧 (
    ID integer,
    名前 varchar(12),
    料金 integer,
    開始時間 time,
    終了時間 time,
    休館日 varchar(3)
    )

insert into 水族館一覧
values (1, '東京臨海水族館', 800, '9:30', '17:00', '月曜日')

insert into 水族館一覧
values (2, '鎌倉 シーパラダイス', 2500, '8:30', '22:30', '無休')

insert into 水族館一覧
values (3, 'ドルフィンドーム', 2000, '10:00', '22:00', '無休')

insert into 水族館一覧
values (4, 'ワンダー水族館', 1500, '10:00', '17:00', '火曜日')

insert into 水族館一覧
values (5, 'TX国際水族館', 2200, '10:00', '18:00', '無休')

select * from 水族館一覧
where 名前 like '%水族館'

select * from 水族館一覧
where 料金 >= 2000

select * from 水族館一覧
where 開始時間 = '8:30'

select * from 水族館一覧
where 開始時間 = '10:00'
or 終了時間 = '17:00'

select * from 水族館一覧
where 開始時間 = '10:00'
and 終了時間 = '17:00'

select * from 水族館一覧
where 休館日 = '月曜日'
or 休館日 = '火曜日'

select * from 水族館一覧
where 休館日 in ('月曜日', '火曜日')

select * from 水族館一覧
where 休館日 <> '無休'

select * from 水族館一覧
where 料金 between 1500 and 2000

update 水族館一覧
set 休館日 = '水曜日'
where ID = 3

delete from 水族館一覧
where ID = 4

select * from 水族館一覧
order by 料金 asc

次に取り組んだのは練習問題で教科書p.132-133です。進めたところの答えだけ書いておきます。
問題4-1

select * from 注文履歴
order by 注文番号 asc, 注文枝番 asc


select 商品名 from 注文履歴
where 日付 >= '2024-01-01'
and 日付 <= '2024-01-31'
order by 商品名 asc


select 注文番号, 注文枝番, 注文金額 from 注文履歴
where 分類 = '1' order by 注文金額
offset 1 rows
fetch next 3 rows only


select 日付, 商品名, 単価, 数量, 注文金額 from 注文履歴
where 分類 = '3' and 数量 >= 2
order by 日付 asc, 数量 desc


select distinct 分類, 商品名, サイズ, 単価 from 注文履歴
where 分類 = '1'
union
select distinct 分類, 商品名, null, 単価 from 注文履歴
where 分類 = '2'
union
select distinct 分類, 商品名, null, 単価 from 注文履歴
where 分類 = '3'
order by 1, 2


6限目は教科書から
p.298-
すべてのSQLは4種類の命令に分類できます。
DMLはデータ操作言語
select, insert, update, deleteなど

DDLはデータ定義言語
createなどの命令

p.304
drop table文
間違って作ってしまった時に消去する操作。
delete文だとデータは消えるが入れ物のテーブルは残る。dropならテーブルごと消せます。

alter table文
項目を追加したり削除するのに使います。実務では使うこともある。
alter table テーブル名 add フィールド名 型;は新しい項目を追加する
alter table テーブル名 drop フィールド名;は削除する

alter table 家計簿
 add 関連日 date;

alter table 家計簿 
drop 関連日;

をdokoqlで実行してみました。

p.308- 制約
ヒューマンエラーに備えた設計で特定の項目について必ず入力しなければエラーが出るようにできる。create tableの中で必須入力を設定する。
次のように型の後ろのdefaultよりも後ろに not nullを置く
メモ varchar(100) default '不明' not null
入金額と出金額をdefault 0 check(入金額 >= 0)としてチェック制約を付ける。これで0以上でなければ受け付けなくなる。

1番のIDに給与を設定して、2、3番目はほかの設定があるときに、4番目も給与になってしまうことがある。重複禁止はuniqueを型の後ろに置く。ここまでの事項をまとめたコードは以下の通り。

create table 家計簿1 ( 
    日付 date not null,
    費目ID integer, 
    メモ varchar(100) default '不明' not null, 
    入金額 integer default 0 check(入金額 >= 0), 
    出金額 integer default 0 check(出金額 >= 0) 
    );
create table 費目 ( 
    ID integer, 
    名前 varchar(40) unique 
    );

それぞれnot null制約、check制約、unique制約という。

p.312- 主キー制約
主キーはレコードを一意に特定するものだった。
IDを主キーにしたい場合、ID integer primary keyとする。主キーに指定するとほかの制約not nullなどを付けなくても自動的に制約がつく。
複合主キーを設定するには
primary key(ID, 名前)とする。

p.230- 第8章
今はリレーショナルDBが主流になっている。AccessというデータベースもRDB。他にもネットワーク型DBなどもある。
p.232- 複数のテーブルにデータを格納する
p.310の表には家計簿テーブル、費目テーブルがあるが、家計簿の費目IDを使えば、費目テーブルにある費目の名称を引っ張ってこれる。ここで費目テーブルのIDは主キー、これに対して家計簿テーブルの費目IDは外部キーという。ほかのテーブルから必要な情報を引っ張ってこれるもの。こうして複数のテーブルを関連させて、select文で一つのテーブルのように見せられる。だからリレーショナルDBという。複数のテーブルに分割できるように学んでいく。

一度決めたらデータが増えないのでそのテーブルを費目マスターなどという。家計簿テーブルのように毎日どんどんデータが増えていくのがトランザクションファイルという。

p.235-
費目の名前を変更する場合
家計簿テーブルに10万行など大量にデータがあるとする。そこから費目の給料を給与手当に変更したい場合、処理が重くなるうえに、変更に漏れが生じるかもしれないが、あらかじめ家計簿テーブルと費目マスターというテーブルに分割していれば、費目マスターの費目項目1つだけ修正すればいい。
分割すると書き足したり、修正するときにミスなども防げるのでマスターテーブルがあるとよい。

p.240-
テーブルの結合
select 日付, 名前 as 費目, メモ
from 家計簿
join 費目
on 家計簿.費目ID = 費目.ID

この記事が気に入ったらサポートをしてみませんか?