プログラミング論 II RDBMSとSQL http://www.ns.kogakuin.ac.jp/~ct13140/Prog.2010/ R-1 概要 • データベース – 簡単.単に覚えるだけ. – 情報系技術者の超重要スキル • リレーション – 抽象的で理解しづらい. 大まかに分かれば良い. • SQL – 易しい.必ず理解すること! R-2 データベース RDBMS R-3 Database • データベースとは,データの集まり. – 例えば,実験の測定値,社員表など. – 多くの場合,数値か文字列. R-4 DBMS (Database Management System) – データベース管理システム.データベースを管 理運用するためのシステム. • 多くの場合,ソフトウェアである. – DBMSには数種類のモデルがある. • リレーショナルデータモデル,ネットワークデータモ デル • 階層型データモデル,オブジェクト指向,XML – 現在,多くのDBMSがリレーショナルデータモデ ルのRDBMB (Relational Database Management System)である. – 本講義ではRDBMSのみ扱う. R-5 RDBMS • RDBMB – Relational Database Management System • 日本語で「関係データベース(管理システム)」 – Relational Data Model(関係データモデル)を 採用したDMBS • 通常,SQLという言語を用いて運用する. • 現在,ほとんどのDBMSがRDBMS – Oracle, Microsoft SQL Server, DB2(IBM), PostgreSQL, MySQL, Firebird, SQLiteなどの実装があ る. • 現在,超重要なアプリケーションの一つ. R-6 単語"Database"の曖昧性 • 「データとDBMS(DB管理システム)」をまとめて 「データベース(DB)」と呼ぶこともある. • DBMS(DB管理システム)を「データベース」と呼 ぶこともある. – RDBMSの意味で使うこともある. R-7 データモデル • DBMSでは各種モデルによりデータを整理, 管理する.この整理,管理のモデルがデー タモデル. • 一般に,以下の3要素から成り立つ – データやデータ間の関連を表現する構造記述 – データやデータ間に存在する一貫性制約の記述. – データの検索,更新などのデータ操作言語 R-8 リレーショナルデータモデル • 数学の集合論に基づく,データモデル. • 極めて簡潔に説明すると「表型」. • 全てのデータ,データ間の関連を「リレー ションのタプル」で表現する.(後述) – タプルは,値の組み合わせ. – Codd(コッド)博士が提案.チューリング賞. – 日本語では「関係データモデル」 R-9 リレーション R-10 リレーショナルデータモデル 会員表 • データを表形式で管理する. 会員番号 氏名 住所 所属 0 福田康夫 群馬県... 部署M 1 安倍晋三 山口県... 部署M 2 小泉純一郎 神奈川県... 部署M 3 森喜朗 石川県... 部署M 4 小渕恵三 群馬県... 部署O R-11 リレーショナルデータモデル 表,リレーション,TABLE 会員番号 氏名 住所 所属 0 福田康夫 群馬県... 部署M 1 安倍晋三 山口県... 部署M 2 小泉純一郎 神奈川県... 部署M 3 森喜朗 石川県... 部署M 4 小渕恵三 群馬県... 部署O R-12 リレーショナルデータモデル 行,ロー, レコード, タプル 会員番号 氏名 住所 所属 0 福田康夫 群馬県... 部署M 1 安倍晋三 山口県... 部署M 2 小泉純一郎 神奈川県... 部署M 3 森喜朗 石川県... 部署M 4 小渕恵三 群馬県... 部署O R-13 リレーショナルデータモデル 列,カラム, フィールド 会員番号 氏名 住所 所属 0 福田康夫 群馬県... 部署M 1 安倍晋三 山口県... 部署M 2 小泉純一郎 神奈川県... 部署M 3 森喜朗 石川県... 部署M 4 小渕恵三 群馬県... 部署O R-14 リレーショナルデータモデル 列名,カラム名, フィールド名 会員番号 氏名 住所 所属 0 福田康夫 群馬県... 部署M 1 安倍晋三 山口県... 部署M 2 小泉純一郎 神奈川県... 部署M 3 森喜朗 石川県... 部署M 4 小渕恵三 群馬県... 部署O R-15 リレーショナルデータモデル • 行の値の変更,行の追加,行の削除 などを繰り返して,DBMSを運用してい く. 会員番号 氏名 住所 • 通常,列の 0 福田康夫 群馬県... 追加/削除は 1 安倍晋三 山口県... 行わない. 2 小泉純一郎 神奈川県... • 行の順は意味 3 森喜朗 石川県... を持たない 4 小渕恵三 群馬県... 所属 部署M 部署M 部署M 部署M 部署O R-16 キー key R-17 候補キー •表内の行を特定できる列(の組)が候補キー. –会員番号を定めると,行が一意に定まる. よって,会員番号は候補キー. •「会員番号」が「2」である行は,1行しかない. •当然,会員番号は重複しないことが前提. –「氏名」では, 同姓同名がいると 破綻する. 会員番号 氏名 住所 所属 0 福田康夫 群馬県... 部署M 1 安倍晋三 山口県... 部署M 2 小泉純一郎 神奈川県... 部署M 3 森喜朗 石川県... 部署M 4 小渕恵三 群馬県... 部署O R-18 候補キー • キーは,複数の列で構成されていても良い. 「氏名,科目」を定めると行が特定される. よって,「氏名,科目」の組は候補キー 氏名 科目 得点 英語 A 数学 B 英語 C 安倍晋三 数学 D 小泉純一郎 英語 E 最悪でも,「全列の組」は 福田康夫 候補キーとなる. (同一の行は存在しては 福田康夫 安倍晋三 ならない.) R-19 候補キー •候補キーは複数存在する場合もある. –会員番号を定めると行が特定される. よって,会員番号は候補キー –基礎年金番号を定めると行が特定される. よって,基礎年期番号も候補キー 会員番号 氏名 住所 基礎年金番号 0 福田康夫 群馬県... 234 1 安倍晋三 山口県... 567 2 小泉純一郎 神奈川県... 890 3 森喜朗 石川県... 123 4 小渕恵三 群馬県... 456 R-20 主キー • 候補キーの中から,DBMS管理者が 主観的に選択した主たるキーが「主キー」. – 理論的価値は低いが,実運用上重要な意味 を持つ – 下線を引くことが多い. 会員番号 氏名 住所 基礎年金番号 0 福田康夫 群馬県... 234 1 安倍晋三 山口県... 567 2 小泉純一郎 神奈川県... 890 3 森喜朗 石川県... 123 4 小渕恵三 群馬県... 456 R-21 正規形 R-22 第一正規形 • 1マスに複数の要素を入れてはならない. • 1個の要素が複数マスに跨ってはならない. – そもそも,RDBMSに格納できない. 注意:この説明は過度に簡潔化されています. そもそも「マス」などという表現は使ってはならない. R-23 第一正規形 会員 番号 0 趣味 氏名 福田康夫 クラシック音楽鑑賞 2 歌舞伎鑑賞 会員 番号 映画鑑賞 0 小泉純一郎 2 会員 番号 0 趣味 氏名 福田康夫 クラシック音楽鑑賞 2 小泉純一郎 歌舞伎鑑賞, 映画鑑賞 非正規形 氏名 趣味 福田康夫 クラシック音楽鑑賞 2 小泉純一郎 歌舞伎鑑賞 2 小泉純一郎 映画鑑賞 第一正規形 R-24 関数従属 • ある列群の値が決まれば,別のある 列群の値が一意に定まるとき「関数従 {氏名,教科}が決まると, 属(する)」という. {点数,合否}は決まる. 氏名 教科 点数 合否 福田康夫 英語 50 否 福田康夫 数学 60 合 安倍晋三 英語 70 合 安倍晋三 数学 80 合 よって,関数従属である. {氏名,教科}→{点数,合否} {氏名}を決めても, {点数}は決まらない. 関数従属でない. {点数}が決まると, {合否}は決まる. 関数従属である. R-25 完全従属 • 列群Aに列群Bが関数従属であり, 列群Aの真部分集合(Aの一部)に 関数従属でないとき,「完全従属」という. 会員 番号 氏名 教科 点数 合否 0 福田康夫 英語 50 否 0 福田康夫 数学 60 合 1 安倍晋三 英語 70 合 1 安倍晋三 数学 80 合 {会員番号,氏名,教科} →{点数,合否}なので関数従属. ところが, {会員番号,教科} →{点数,合否}でもある. 実は,{氏名}は無くても良い. よって,{点数,合否}は {会員番号,氏名,教科}に 完全従属でない. R-26 第二正規形 • 第一正規形である. • 候補キーでない列が候補キーに完全従属 している. R-27 第二正規形でない例 赤枠は主キー user name ID email 年 表"日記" 月 日 text 0 福田 [email protected] 2007 9 26 首相になった 1 安倍 [email protected] 2007 7 29 選挙を行った 1 安倍 [email protected] 2006 9 26 首相になった 2 小泉 [email protected] 2005 8 8 解散した {userID,年,月,日}が候補キーかつ主キー. {userID}→{name,email}で, nameやemailが候補キーに完全従属でない. R-28 第二正規化の例 user name ID email user ID 年 月 日 text 0 福田 [email protected] 0 2007 9 26 首相になった 1 安倍 [email protected] 1 2007 7 29 選挙を行った 2 小泉 [email protected] 1 2006 9 26 首相になった 表"ユーザ表" 2 2005 8 8 解散した 表"日記" • 先ほどの表を分解し, 非候補キーが全ての候補キーに完全従属. これで,第二正規形 R-29 第三正規形 • 第二正規形である. • 全ての非キー列は,どの候補キーにも推 移的に従属しない. R-30 第三正規形でない例 user name ID 所属 勤務地 0 福田 A事業部 八王子 1 安倍 B事業部 新宿 2 小泉 B事業部 新宿 3 森 A事業部 八王子 • 第二正規形であるが, 所属→勤務地の関数 従属が存在する. • つまり,勤務地は • userID→所属 →勤務地 と 推移的に決定される. 分解するべき R-31 第三正規形 user name 所属 勤務地 ID 0 福田 A事業部 八王子 1 安倍 B事業部 新宿 2 小泉 B事業部 新宿 3 森 A事業部 八王子 user name 所属 ID 0 福田 A事業部 1 安倍 B事業部 2 小泉 B事業部 3 森 所属 勤務地 A事業部 八王子 B事業部 新宿 A事業部 R-32 SQL R-33 SQL • SQLは,RDBMSを操作するのに使用する 言語の一つ. – 現在,本言語が主流.本稿ではSQLのみ扱う. – 厳密には,SQLは略語ではない. • 歴史的背景から"Structured Query Language"の略とすることもある. • 構造化問い合わせ言語. – 言語仕様には,実装依存する箇所が多々ある. • C言語にも方言はあるが,SQLほど酷くはない. R-34 SQLの超基本命令 • 表を作成する. CREATE TABLE 表名 (...); • 表に行を挿入する. INSERT INTO 表名 VALUES (...); • 表の内容を確認する. SELECT * FROM 表名; • 表の行の値を変更する. UPDATE 表名 SET 列名=値[,列名=値] WHERE ..; • 表の行を削除す DELETE FROM 表名 WHERE ...; R-35 SQLの例 • 以下の様なデータベースを構築することを 考える. 表"user_tbl" userID name email 0 Fukuda Yasuo [email protected] 1 Abe Shinzo [email protected] 2 3 Koizumi Junichiro [email protected] Mori Yoshiro [email protected] R-36 SQLの例 userID name ユーザID ユーザ名を格納する. を格納. 最大64文字とする. INTEGER 型とする. VARCHAR(64)型 とする. email ユーザのE-mailアドレス を格納する. 最大64文字とする. VARCHAR(64)型 とする. • 各行(レコード)の列(フィールド)には「型」が ある. R-37 SQL (CREATE TABLE) CREATE TABLE user_tbl ( userID integer, name varchar(64), email varchar(64) ); R-38 • 空の表"user_tbl"が作成される. – 確認方法は後述. userID name 表"user_tbl" email R-39 SQL (INSERT INTO) INSERT INTO user_tbl VALUES ( 0, 'Fukuda Yasuo', '[email protected]' ); これが, userIDになる. これが, nameになる. これが, emailになる. R-40 • 表"user_tbl"に1行追加される. – 確認方法は後述. 表"user_tbl" userID name email 0 Fukuda Yasuo [email protected] R-41 SQL (INSERT INTO) INSERT INTO user_tbl VALUES ( 1, 'Abe Shinzo', '[email protected]' ); INSERT INTO user_tbl VALUES ( 2, 'Koizumi Junichiro', '[email protected]' ); R-42 • 表"user_tbl"に2行追加される. – 確認方法は後述. 表"user_tbl" userID name email 0 Fukuda Yasuo [email protected] 1 Abe Shinzo [email protected] 2 Koizumi Junichiro [email protected] R-43 SQL (SELECT/FROM) SELECT * FROM user_tbl; 結果 userID name email 0 Fukuda Yasuo [email protected] 1 Abe Shinzo [email protected] 2 Koizumi Junichiro [email protected] R-44 SQL (SELECT/FROM) • SELECT name, email FROM user_tbl; 結果 name email Fukuda Yasuo [email protected] Abe Shinzo [email protected] Koizumi Junichiro [email protected] R-45 SQL (SELECT/FROM) SELECT * FROM user_tbl WHERE userID=2;結果 userID 2 name email Koizumi Junichiro [email protected] SELECT * FROM…; この部分では, 列の選択を行う. SELECT * FROM … WHERE userID=2; この部分では, 行の選択を行う. R-46 SQL (SELECT/FROM/WHERE) SELECT * FROM user_tbl WHERE 1<=userID; 結果 userID name email 1 Abe Shinzo [email protected] 2 Koizumi Junichiro [email protected] R-47 SQL (UPDATE) UPDATE user_tbl SET email= '[email protected]' WHERE userID=0; SELECT * FROM user_tbl; 結果 userID name email 0 Fukuda Yasuo [email protected] 1 Abe Shinzo [email protected] 2 Koizumi Junichiro [email protected] R-48 SQL (DELETE) DELETE FROM user_tbl WHERE userID=0; SELECT * FROM user_tbl; 結果 userID name email 1 Abe Shinzo [email protected] 2 Koizumi Junichiro [email protected] R-49 データ型 整数型 INTEGER型:整数値を格納. SMALLINT型,NUMERIC型,DECIMAL型 浮動小数点型 REAL型:単精度浮動小数点 DOUBLE PRECISION型:倍精度浮動小 数点 FLOAT型 R-50 データ型 文字列型 CHARACTER(n):n文字以内の文字列 VARCHAR(n):n文字以内の文字列 n文字より短い文字列を格納したとき, CHARACTER型の場合,不足分は空白で埋められ n文字分容量が消費される. VARCHAR型の場合は,埋められない. VARCHAR型の使用の方が一般的と思われる. R-51 データ型 日付型 DATE型:日付を表す. TIME型:時刻 TIMESTAMP:日付と時刻 R-52 データ型 • データ型はRDBMS実装に依存する部分が 大きい. • 詳細は,実装ごとのマニュアルを読む必要 がある. R-53 NULL値 • RDBMSのマスを空にすることができる(場 合がある) • 空を「NULL」と呼ぶ. • 主キーやNOT NULL制約のついた列のマ スは,NULLにできない. • 注意:一般にRDBMSに「マス」という表現は ない. R-54 算術演算子 使用例 意味 + a+b aとbの和 - a-b aとbの差 * a*b aとbの積 / a/b aをbで割った商 % a%b aとbで割った余り R-55 比較演算子 使用例 意味 = a=b aとbは等しい < a<b aはbより小さい <= a<=b aはb以下 > a>b aはbより大きい >= <> != a>=b aはb以上 a!=b aとbは等しくない R-56 論理演算子 使用例 意味 A and B A かつ B 10<=a and a <= 20 aが10以上 かつ aが20以下 A or B A または B a<=10 or 20<=a aが10以下 または aが20以上 NOT A A でない NOT (a = 100) Aが100でない AND OR NOT R-57 SELECTの応用 • 以下の様な表があるとする. 表"user_tbl" userID name email 0 Fukuda Yasuo [email protected] 1 Abe Shinzo [email protected] 2 Koizumi Junichiro [email protected] R-58 SELECT SELECT name FROM user_tbl; name Fukuda Yasuo Abe Shinzo Koizumi Junichiro R-59 SELECT/WHERE SELECT * FROM user_tbl WHERE userID = 2; userID 2 name email Koizumi Junichiro [email protected] R-60 SELECT/WHERE SELECT * FROM user_tbl WHERE userID < 2; userID name email 0 Fukuda Yasuo [email protected] 1 Abe Shinzo [email protected] R-61 SELECT/WHERE SELECT * FROM user_tbl WHERE name = 'Koizumi Junichiro'; userID 2 name email Koizumi Junichiro [email protected] R-62 SELECT/WHERE SELECT * FROM user_tbl WHERE 0<userID AND userID<2; userID name email 1 Abe Shinzo [email protected] R-63 SELECT/WHERE SELECT * FROM user_tbl WHERE userID BETWEEN 1 AND 2; userID name email 1 Abe Shinzo [email protected] 2 Koizumi Junichiro [email protected] userIDが「1以上2以下」 R-64 SELECT/WHERE SELECT * FROM user_tbl WHERE userID IN (0,2); userID name email 0 Fukuda Yasuo [email protected] 2 Koizumi Junichiro [email protected] userIDが「0か2」 R-65 SELECT/WHERE SELECT * FROM user_tbl WHERE userID NOT IN (0,2); userID name email 1 Abe Shinzo [email protected] R-66 SELECT/ORDER BY 表"user_tbl" userID name score 0 Fukuda Yasuo 80 1 Abe Shinzo 70 2 Koizumi Junichiro 90 注意:この順は 保証されていない SELECT * FROM user_tbl; userID name score 0 Fukuda Yasuo 80 1 Abe Shinzo 70 2 Koizumi Junichiro 90 R-67 SELECT/ORDER BY userID name score 0 Fukuda Yasuo 80 1 Abe Shinzo 70 2 Koizumi Junichiro 90 SELECT * FROM user_tbl ORDER BY score; userID name score 1 Abe Shinzo 70 0 Fukuda Yasuo 80 2 Koizumi Junichiro 90 R-68 SELECT/ORDER BY userID name score 0 Fukuda Yasuo 80 1 Abe Shinzo 70 2 Koizumi Junichiro 90 SELECT * FROM user_tbl ORDER BY score DESC; userID name score 2 Koizumi Junichiro 90 0 Fukuda Yasuo 80 1 Abe Shinzo 70 R-69 SELECT/ORDER BY userID name score 0 Fukuda Yasuo 80 1 Abe Shinzo 70 2 Koizumi Junichiro 90 SELECT * FROM user_tbl ORDER BY score ASC; userID name score 1 Abe Shinzo 70 0 Fukuda Yasuo 80 2 Koizumi Junichiro 90 R-70 SELECT/ORDER BY SELECT * FROM user_tbl ORDER BY score, age; まず,"score"の順に並び替え, それが同じ値だったら"age"で並び替える. R-71 LIKE演算子 と % と _ LIKE演算子 文字列を比較するのに使用する. 下記の,パターンマッチが使用可能. % (パーセント) 任意の長さ(0文字以上)の,任意の文字にマッ チする. _ (アンダースコア) 1文字の任意の文字にマッチする. R-72 % と _ の例 ABC, AAC, AAB があるとき, 「A_C」は, ABC と AAC が該当. ABC は,「_がB」と考えれば該当. AAC は,「_がA」と考えれば該当. R-73 % と _ の例 ABC, AAC, AAB があるとき, 「_A_」は, AAC と AAB が該当. AAC は,「_と_が,AとC」と考えれば該当. AAB は,「_と_が,AとB」と考えれば該当. R-74 % と _ の例 ABC, AA, A, BAA があるとき, 「A%」は, ABC, AA, A が該当. ABC は,「%が,"BC"」と考えれば該当. AA は,「%が,"A"」と考えれば該当. A は,「%が,""」と考えれば該当.(0文字でもOK) BAA は,%をどのようにおいても該当しない. R-75 % と _ の例 ABC, AA, BAA, B があるとき, 「%A%」は, ABC, AA, BAA が該当. ABC は,「%と%が,""と"BC"」と考えれば該当. AA は,「%と%が,"A"と""」と考えれば該当. 「%と%が,""と"A"」と考えても該当. BAA は,「%と%が,"B"と"A"」と考えれば該当. 「%と%が,"BA"と""」と考えれば該当. B は,%をどのようにおいても該当しない. R-76 文字'%'を検索するとき '%'をそのまま書くと,特殊な意味になってしまう. LIKE '100%'には,「100%」ではなく「100から始まる 任意の文字列」が該当してしまう. LIKE '100\%'とすれば「100%」の意味になる. LIKE '%\%'は,「~%」がマッチする.(%で終わる任意 の文字列) R-77 LIKE演算子 userID name 0 ABC 1 BBC 2 BBCC userID name 3 BC 0 ABC 4 BAC 1 BBC 5 B 2 BBCC 表"user_tbl" SELECT * FROM user_tbl WHERE name LIKE '_B%'; R-78 関数 R-79 本講義で頻繁に用いる表の設計 表"usertbl" userID name passwd email 登録ユーザの表 0 fukuda yasu [email protected] 1 abe shin [email protected] 2 koizumi jun [email protected] 3 mori yoshi [email protected] 表"TODOtbl" TODOID userID 0 0 1 0 2 2 3 2 4 3 txt 組閣 演説 民営化 解散 選挙 各ユーザが入力した TODOデータ R-80 SELECT と 関数 SECECT name FROM user_tbl; SELECT UPPER(name), name FROM user_tbl; name UPPER(name) name Fukuda Yasuo FUKUDA YASUO Fukuda Yasuo Abe Shinzo ABE SHINZO Abe Shinzo Koizumi Junichiro KOIZUMI JUNICHIRO Koizumi Junichiro UPPER関数は,文字列を大文字に変換. LOWER関数は,文字列を小文字に変換. R-81 SELECT と 関数 userID name score 0 Fukuda Yasuo 80 1 Abe Shinzo 70 2 Koizumi Junichiro 90 SELECT SUM(score) FROM user_tbl; SUM(score) 240 SUM関数は,合計を返す. R-82 SELECT と 関数 userID name score 0 Fukuda Yasuo 80 1 Abe Shinzo 70 2 Koizumi Junichiro 90 SELECT AVG(score) FROM user_tbl; SUM(score) 80 AVG関数は,平均を返す. R-83 SELECT と 関数 userID name score 0 Fukuda Yasuo 80 1 Abe Shinzo 70 2 Koizumi Junichiro 90 SELECT COUNT(*) FROM user_tbl; COUNT(*) 3 COUNT関数は,件数を返す. R-84 SELECT と 関数 userID name score 0 Fukuda Yasuo 1 1 Abe Shinzo 1 2 Koizumi Junichiro 2 SELECT COUNT(ALL score) FROM user_tbl; COUNT(ALL score) 3 COUNT関数は,件数を返す. 列名を指定しても良い. R-85 SELECT と 関数 userID name score 0 Fukuda Yasuo 1 1 Abe Shinzo 1 2 Koizumi Junichiro 2 SELECT COUNT(DISTINCT score) FROM user_tbl; COUNT(DISTINCT score) COUNT関数は,件数を返す. 2 DISTINCTを付けると 重複は1件として数える. R-86 SELECT と 関数 userID name score 0 Fukuda Yasuo 1 1 Abe Shinzo 1 2 Koizumi Junichiro 2 SELECT COUNT(*) FROM user_tbl WHERE score=1; COUNT(DISTINCT score) 2 score=1の件数を数える. R-87 SELECT と 関数 • 関数MAX()は,最大値を返す. • 関数MIN()は,最小値を返す. R-88 練習 studentID class score 0 A 10 1 A 20 2 A 30 3 B 40 4 B 50 5 B 60 クラスAの学生(3人)の平均点を出すSQL文は? R-89 SQLのGROUP BY R-90 GROUP BY • 指定した列の値が同じなら,それらをまと めて1個のGROUPにすることが可能 R-91 GROUP BY の例 userID 0 1 2 3 4 class M M M M O name fukuda abe koizumi mori obuchi 表:usrtbl SELECT * FROM usertbl; userID 0 1 2 3 4 class M M M M O name fukuda abe koizumi mori obuchi R-92 GROUP BY の例 userID 0 1 2 3 4 class M M M M O name fukuda abe koizumi mori obuchi 表:usrtbl class M M M M SELECT class FROM usrtbl; O SELECT class FROM usrtbl GROUP BY class; class M O R-93 GROUP BY の例 userID 0 1 2 3 4 class M M M M O name fukuda abe koizumi mori obuchi 表:usrtbl SELECT class, count(class) FROM usrtbl GROUP BY class; class M O count 4 1 R-94 GROUP BY の例 userID 0 1 2 3 4 class M M M M O name fukuda abe koizumi mori obuchi 表:usrtbl SELECT * FROM usrtbl GROUP BY class; これはERROR! userID ?? ?? class M O name ?? ?? ここに表示すべき項目が, 定まらない! fukuda? abe? koizumi? mori? R-95 DISTINCT (GROUP BYと類似) userID 0 1 2 3 4 class M M M M O name fukuda abe koizumi mori obuchi 表:usrtbl class M M M M SELECT class FROM usrtbl; O SELECT class FROM usrtbl GROUP BY class; class M O SELECT DISTINCT class FROM usrtbl; R-96 DISTINCTとGROUP BY • DISTINCTは単に重複データを削除する のみ • GROUP BYはグループ化し,その後集合 関数を用いるのが一般的. R-97 DISTINCTとGROUP BY DISTINCT編 userID 0 1 2 3 4 class M M M M O name fukuda abe koizumi mori obuchi 表:usrtbl class M M M SELECT class FROM usrtbl; M O 重複を削除 class SELECT DISTINCT class FROM usrtbl; M O R-98 DISTINCTとGROUP BY GROUP BY編 userID 0 1 2 3 4 class M M M M O name fukuda abe koizumi mori obuchi 表:usrtbl "GROUP BY class"によるグループ化 userID 0 1 2 3 4 class M O name fukuda abe koizumi mori obuchi R-99 DISTINCTとGROUP BY GROUP BY編 userID 0 1 2 3 4 class M O name fukuda abe koizumi mori obuchi 表:usrtblを GROUP BY classしたもの SELECT class FROM usrtbl GROUP BY class; class M O R-100 DISTINCTとGROUP BY GROUP BY編 userID class name 表:usrtblを 0 fukuda GROUP BY classしたもの 1 abe M 2 koizumi 3 mori 4 O obuchi SELECT class, count(class) FROM usrtbl GROUP BY class; class count M 4 O 1 R-101 GROUP BY userID 0 1 2 3 4 class M M M M O blood A B A O A 表:usrtbl name fukuda abe koizumi mori obuchi classと blood が同じ SELECT class,blood FROM usrtbl GROUP BY class, blood; class blood M A ←ここには fukuda と koizumi がある M M O B O A ←ここには abe がある ←ここには mori がある ←ここには obuchi がある R-102 GROUP BY userID 0 1 2 3 4 class M M M M O blood A B A O A name fukuda abe koizumi mori obuchi 表:usrtbl classと blood が同じ SELECT class,blood,count(*) FROM usrtbl GROUP BY class, blood; class blood count M A 2 ←fukuda と koizumi M M O B O A 1 1 1 ←abe ←mori ←obuchi R-103 結合 JOIN R-104 結合 • 2個の表を組み合わせて,別の表を作成 する操作を「結合」という – 交差結合(CROSS JOIN) – 内部結合(INNER JOIN) – 左外部結合(LEFT OUTER JOIN) – 右外部結合(RIGHT OUTER JOIN) – 全外部結合(FULL OUTER JOIN) R-105 交差結合 表"tblA" aID 0 1 2 表"tblB" bID 0 1 4 CROSS JOIN tblA.aID 0 0 0 1 1 1 2 2 2 tblB.bID 0 1 4 0 1 4 0 1 4 R-106 内部結合 表"tblA" aID 0 1 2 表"tblB" bID 0 1 4 INNER JOIN ON tblA.aID = tblB.bID tblA.aID 0 1 tblB.bID 0 1 R-107 左外部結合 表"tblA" aID 0 1 2 表"tblB" bID 0 1 4 LEFT OUTER JOIN ON tblA.aID = tblB.bID tblA.aID 0 1 2 tblB.bID 0 1 NULL R-108 左外部結合 表"tblA" aID 0 1 2 表"tblB" bID 0 1 4 RIGHT OUTER JOIN ON tblA.aID = tblB.bID tblA.aID 0 1 NULL tblB.bID 0 1 4 R-109 全外部結合 表"tblA" aID 0 1 2 表"tblB" bID 0 1 4 RIGHT OUTER JOIN ON tblA.aID = tblB.bID tblA.aID 0 1 2 NULL tblB.bID 0 1 NULL 4 R-110 交差結合 CROSS JOIN 表"a" id 0 1 2 表"b" name fukuda abe CROSS JOIN 3列の表と, 2列の表を交差結合 すると, 3×2=6列になる. id 0 0 1 1 2 2 • 両表の1列ずつを 組み合わせて(横 に並べて)新しい表 を作成. name • 全組み合わせ存在. fukuda abe fukuda abe fukuda abe R-111 交差結合 CROSS JOIN 表"a" id 0 1 2 表"b" name fukuda abe CROSS JOIN id 0 0 1 1 2 2 表aと表bの交差結合を得るには, SELECT * FROM a CROSS JOIN b; SELECT * FROM a, b; name fukuda abe fukuda abe fukuda abe id | name ----+-------0 | fukuda 0 | abe 1 | fukuda 1 | abe 2 | fukuda 2 | abe R-112 交差結合 CROSS JOIN 表"usertbl" userID name 0 fukuda 1 abe 2 koizumi 登録ユーザの表 CROSS JOIN userID=1と userID=2を 横に並べた行. あまり意味がない userID 0 0 0 1 1 1 2 2 2 表"TODOtbl" TODOID userID txt 0 0 組閣する 1 0 演説する 2 2 解散する 各ユーザが入力したTODOデータ name TODOID userID fukuda 0 0 fukuda 1 0 fukuda 2 2 abe 0 0 abe 1 0 abe 2 2 koizumi 0 0 koizumi 1 0 koizumi 2 2 txt 組閣する 演説する 解散する 組閣する 演説する 解散する 組閣する 演説する 解散する R-113 内部結合 INNER JOIN 表"usertbl" userID name 0 fukuda 1 abe 2 koizumi INNER JOIN on usertbl.userID = TODOtbl.userID • 交差結合のうち,条 件にあうもののみを 選択. TODOID userID txt 0 1 2 userID name TODOID userID 0 fukuda 0 0 0 fukuda 1 0 2 koizumi 2 2 0 0 2 組閣する 演説する 解散する 表"TODOtbl" txt 組閣する 演説する 解散する R-114 内部結合 INNER JOIN 表"usertbl" userID name 0 fukuda 1 abe 2 koizumi INNER JOIN on usertbl.userID = TODOtbl.useriD userID 0 0 0 1 1 1 2 2 2 表"TODOtbl" TODOID userID 0 0 1 0 2 2 name TODOID userID fukuda 0 0 fukuda 1 0 fukuda 2 2 abe 0 0 abe 1 0 abe 2 2 koizumi 0 0 koizumi 1 0 koizumi 2 2 txt 組閣する 演説する 解散する txt 組閣する 演説する 解散する 組閣する 演説する 解散する 組閣する 演説する 解散する R-115 内部結合 INNER JOIN 表"usertbl" userID name 0 fukuda 1 abe 2 koizumi 表"TODOtbl" TODOID userID 0 0 1 0 2 2 txt 組閣する 演説する 解散する INNER JOIN on usertbl.userID = TODOtbl.userID userID name TODOID userID 0 fukuda 0 0 0 fukuda 1 0 2 koizumi 2 2 txt 組閣する 演説する 解散する R-116 内部結合 INNER JOIN • SELECT * FROM usertbl INNER JOIN TODOtbl on usertbl.userID = TODOtbl.userID; • SELECT * FROM usertbl, TODOtbl WHERE usertbl.userID = TODOtbl.userID; R-117 内部結合 INNER JOIN •SELECT対象の列を指定するには,表名を明記する. SELECT TODOtbl.TODOID, TODOtbl.txt, usertbl.name FROM TODOtbl INNER JOIN usertbl ON TODOtbl.userID = usertbl.userID; TODOID 0 1 2 txt 組閣する 演説する 解散する name fukuda fukuda koizumi R-118 内部結合 INNER JOIN 表"usertbl" userID name 0 fukuda 1 abe 2 koizumi 表"TODOtbl" TODOID userID 0 0 1 0 2 2 txt 組閣する 演説する 解散する SELECT * FROM usertbl INNER JOIN TODOtbl on usertbl.userid = TODOtbl.userid; userID | name | TODOID | userID | txt --------+---------+--------+--------+-------0 | fukuda | 0 | 0 | 組閣する 0 | fukuda | 1 | 0 | 演説する 2 | koizumi | 2 | 2 | 解散する R-119 外部結合 • 左外部結合,右外部結合,全外部結合と ある. • 交差結合,内部結合と同様だが, 相手の表に対応するものが無い場合も表 示される. – 対応するものが無い場合は,NULLで表示 R-120 左外部結合 LEFT OUTER JOIN • 左外部結合は,(例え右の表に対応する 行が無くても)左の表の行は必ず表示され る. – 右の表に対応する行が無い場合はNULLを表 示 SELECT 左の表 * FROM tblA LEFT OUTER JOIN tblB 右の表 on ...; R-121 左外部結合 LEFT OUTER JOIN 表"usertbl" userID name 0 fukuda 1 abe 2 koizumi 表"TODOtbl" TODOID userID 0 0 1 0 2 2 txt 組閣する 演説する 解散する SELECT * from usertbl LEFT OUTER JOIN TODOtbl on usertbl.userID = TODOtbl.userid; userID 0 name fukuda TODOID 0 1 1 abe 該当なし 2 koizumi 2 userID 0 0 2 txt 組閣する 演説する 解散するR-122 左外部結合 LEFT OUTER JOIN 表"usertbl" userID name 0 fukuda 1 abe 2 koizumi 表"TODOtbl" TODOID userID 0 0 1 0 2 2 txt 組閣する 演説する 解散する SELECT * from usertbl LEFT OUTER JOIN TODOtbl on usertbl.userID = TODOtbl.userid; userID name TODOID 0 fukuda 0 0 fukuda 1 1 abe NULL 2 koizumi 2 userID 0 0 NULL 2 txt 組閣する 演説する NULL 解散する R-123 左外部結合 LEFT OUTER JOIN 表"TODOtbl" TODOID userID 0 0 1 0 2 2 txt 組閣する 演説する 解散する 表"usertbl" userID name 0 fukuda 1 abe 2 koizumi SELECT * from TODOtbl LEFT OUTER JOIN usertbl on TODOtbl.userID = usertbl.userid; TODOID 0 1 2 userID 0 0 2 txt 組閣する 演説する 解散する userID name 0 fukuda 0 fukuda 2 koizumi R-124 左外部結合 LEFT OUTER JOIN 表"TODOtbl" TODOID userID 0 0 1 0 2 2 txt 組閣する 演説する 解散する 表"usertbl" userID name 0 fukuda 1 abe 2 koizumi SELECT * FROM TODOtbl LEFT OUTER JOIN usertbl on TODOtbl.userID = usertbl.userid; TODOID 0 1 2 userID 0 0 2 txt 組閣する 演説する 解散する userID name 0 fukuda 0 fukuda 2 koizumi R-125 右外部結合 RIGHT OUTER JOIN • 右外部結合は,(例え左の表に対応する 行が無くても)右の表の行は必ず表示され る. – 左の表に対応する行が無い場合はNULLを表 示 SELECT * FROM tblA LEFT OUTER JOIN tblB 左の表 右の表 on ...; R-126 右外部結合 RIGHT OUTER JOIN 表"usertbl" userID name 0 fukuda 1 abe 2 koizumi 表"TODOtbl" TODOID userID 0 0 1 0 2 2 SELECT * FROM usertbl RIGHT OUTER JOIN TODOtbl = TODOtbl.userid; userIDon usertbl.userID name TODOID userID txt 組閣する 演説する 解散する 0 fukuda 0 0 txt 組閣する 1 abe 1 0 演説する 2 koizumi 2 2 解散する R-127 右外部結合 RIGHT OUTER JOIN 表"usertbl" userID name 0 fukuda 1 abe 2 koizumi 表"TODOtbl" TODOID userID 0 0 1 0 2 2 txt 組閣する 演説する 解散する SELECT * FROM usertbl RIGHT OUTER JOIN TODOtbl = TODOtbl.userid; userIDon usertbl.userID name TODOID userID txt 0 1 2 fukuda abe koizumi 0 1 2 0 0 2 組閣する 演説する 解散する R-128 右外部結合 RIGHT OUTER JOIN 表"TODOtbl" TODOID userID 0 0 1 0 2 2 txt 組閣する 演説する 解散する 表"usertbl" userID name 0 fukuda 1 abe 2 koizumi SELECT * FROM TODOtbl RIGHT OUTER JOIN usertbl usertbl.userIDtxt = TODOtbl.userid; TODOIDon userID userID 0 1 0 0 組閣する 演説する 該当無し 2 2 解散する 0 name fukuda 1 abe 2 koizumi R-129 右外部結合 RIGHT OUTER JOIN 表"TODOtbl" TODOID userID 0 0 1 0 2 2 表"usertbl" userID name 0 fukuda 1 abe 2 koizumi txt 組閣する 演説する 解散する SELECT * FROM TODOtbl RIGHT OUTER JOIN usertbl usertbl.userIDtxt = TODOtbl.userid; TODOIDon userID userID name 0 1 NULL 2 0 0 NULL 2 組閣する 演説する NULL 解散する 0 0 1 2 fukuda fukuda abe koizumi R-130 全外部結合 FULL OUTER JOIN • 全外部結合は,左外部結合と右外部結合 の両方の要素が表示される. – 左の表に対応する行が無い場合は,左の表 の列にNULLを表示 – 右の表に対応する行が無い場合は,右の表 の列にNULLを表示 R-131 全外部結合 FULL OUTER JOIN 表"usertbl" userID name 0 fukuda 1 abe 2 koizumi 表"TODOtbl" TODOID userID 0 0 1 0 2 2 3 4 txt 組閣する 演説する 解散する 公演する SELECT * FROM usertbl FULL OUTER JOIN TODOtbl on usertbl.userID = TODOtbl.userid; userID name TODOID 0 fukuda 0 0 fukuda 1 1 abe NULL 2 koizumi 2 NULL NULL 3 userID 0 0 NULL 2 4 txt 組閣する 演説する NULL 解散する 公演する R-132 関係代数 R-133 和両立 • 2個の表があり, 「両表の次数(列数)が等しい」かつ 「各列の意味が等しい」とき 「和両立」という. 表"連絡表" 名前 連絡先 123-456 福田 789-012 安倍 345-678 小泉 表"ユーザ表" ユーザ名 電話番号 345-678 小泉 901-234 森 両表は ・列数が等しい(ともに3列) ・各列の意味が等しい ので,「和両立」である. R-134 和集合演算 • 和両立な表Rと表Sがあり,「和集合演算」 とは以下の演算. • それぞれの表の全行をあわせた表を作成 する演算が「和集合演算」. ただし,重複する行は1行にまとめる. – 集合論(RDBMS),では「同一の行が2回以上 登場」することは許されない. – 実際は,RDBMSに全く同じ行を2個以上作成し てもエラーにならないことが多い. • 「R∪S」と記述.論理和に近い感覚. R-135 和集合演算 表"連絡表" 名前 連絡先 123-456 福田 789-012 安倍 345-678 小泉 和集合演算 「小泉,345-678」が2回 登場することはない 表"ユーザ表" ユーザ名 電話番号 345-678 小泉 901-234 森 名前 福田 安倍 小泉 森 連絡先 123-456 789-012 345-678 901-234 R-136 差集合演算 • 和両立な表Rと表Sがあり,「差集合演算」 とは以下の演算. • 表Rから,「表Sに登場する行」を削除した 表を作成するのが差集合演算. – 「Sに登場するが,Rに登場しない行」は(削除 対象が存在せず)削除されない. • 「R-S」と記述 R-137 差集合演算 表"連絡表" 名前 連絡先 123-456 福田 789-012 安倍 345-678 小泉 表"ユーザ表" ユーザ名 電話番号 345-678 小泉 901-234 森 名前 福田 安倍 差集合演算 連絡先 123-456 789-012 小泉 345-678 ←"連絡表"からこの行が削除された 森 901-234 ← この行は"連絡表"に無いので, R-138 特に何も起きない. 共通集合演算 • 和両立な表Rと表Sがあり,「共通集合演 算」とは以下の演算. • 表Rと表Sの両方に登場する行で構成され る表を作成するのが,共通集合演算. • 「R∩S」と記述.論理積に近い感覚. R-139 共通集合演算 表"連絡表" 名前 連絡先 123-456 福田 789-012 安倍 345-678 小泉 共通集合演算 表"ユーザ表" ユーザ名 電話番号 345-678 小泉 901-234 森 名前 小泉 連絡先 345-678 R-140 直積演算 • 前述の交差結合をおこなうこと. • 演算対象の表Rと表Sは和両立である必要 はない. • 「R×S」と記述. R-141 直積演算 表"連絡表" 名前 連絡先 123-456 福田 789-012 安倍 345-678 小泉 表"商品表" 商品名 牛乳 ジュース 価格 100 120 直積集合演算 名前 福田 福田 安倍 安倍 小泉 小泉 連絡先 123-456 123-456 789-012 789-012 345-678 345-678 商品名 牛乳 ジュース 牛乳 ジュース 牛乳 ジュース 価格 100 120 100 120 100 120 R-142 射影演算 • 表から特定の列を抜き出す演算 • SELECT ?? FROM ...; ここで 行っている. R-143 射影演算 表"連絡表" 名前 連絡先 123-456 福田 789-012 安倍 345-678 小泉 射影演算 名前 福田 安倍 小泉 R-144 選択演算 • 表から特定の行を抜き出す演算 • SELECT * FROM WHERE ??; ここで 行っている. R-145 射影演算 表"連絡表" 名前 連絡先 123-456 福田 789-012 安倍 345-678 小泉 選択演算 名前 安倍 小泉 連絡先 789-012 345-678 R-146 結合演算 • 「結合演算」とは, 表Rと表SがありR×S(直積)の中から それぞれの属性値を用いて特定の行を選 択したもの. • 演算対象の表Rと表Sは和両立である必要 はない. • 前述のSQLの結合演算. R-147 商演算 • 表Rと表Sの商演算は,「R÷S」と記述. Rの列数>Sの列数であることが必要. • 説明は,次スライドの例を用いて行う. • 代数的定義は R÷S={ t | t∈R ∧ (∀u∈S)((t , u)∈R) } R-148
© Copyright 2024 ExpyDoc