属性間の従属性を SQL で確認する
テーブル R が属性 a1, a2, ..., am, b1, b2, ..., bn およびその他の属性を持ち, 関数従属性 a1, a2, ..., am -> b1, b2, ..., bn があるとき, 次の SQL の結果では,1番目の属性値が「1」になる.
create table S AS select distinct a1, a2, ..., am, b1, b2, ..., bn from R; select count(*), a1, a2, ..., am from S group by a1, a2, ..., am;
SQLite 3の SQL の説明は http://www.hwaci.com/sw/sqlite/lang.html (English Web Page) にある.
SQLite 3 について: 別ページ »にまとめ
ここでは, データベース名を指定せず,インメモリ・データベースを用いている.
sqlite3
create table SCORE ( name text not null, teacher_name text not null, student_name text not null, score INTEGER not null CHECK ( score >= 0 AND score <= 100 ) ); insert into SCORE values( 'Database', 'K', 'KK', 85 ); insert into SCORE values( 'Database', 'K', 'AA', 75 ); insert into SCORE values( 'Database', 'K', 'LL', 90 ); insert into SCORE values( 'Programming', 'A', 'KK', 85 ); insert into SCORE values( 'Programming', 'A', 'LL', 75 );
select * from SCORE;
結果では,1番目の属性値が「1」になる.
create table S AS select distinct name, teacher_name from SCORE; select count(*), name from S group by name;
結果では,1番目の属性値が「1」になる.
drop table S; create table S AS select distinct name, student_name, score from SCORE; select count(*), name, student_name from S group by name, student_name;
SQLite 3の終了
.exit
ここでは, データベース名を指定せず,インメモリ・データベースを用いている.
sqlite3
create table SCORE ( name text not null, teacher_name text not null, student_name text not null, score INTEGER not null CHECK ( score >= 0 AND score <= 100 ) ); insert into SCORE values( 'Database', 'K', 'KK', 85 ); insert into SCORE values( 'Database', 'K', 'AA', 75 ); insert into SCORE values( 'Database', 'K', 'LL', 90 ); insert into SCORE values( 'Programming', 'A', 'KK', 85 ); insert into SCORE values( 'Programming', 'A', 'LL', 75 );
select * from SCORE;
SCORE( name, teacher_name, student_name, score )を 2つのテーブル
に分解.テーブルを分解するときは重複行を除去するという規則があることに注意.DISTINCTを使う.
create table A as select distinct name, teacher_name from SCORE; create table B AS select distinct name, student_name, score from SCORE;
select * from A;
select * from B;
select A.name, A.teacher_name, B.student_name, B.score from A, B where A.name = B.name;
テーブル SCORE は,テーブル A と B から復元できるから,データベース設計として.
という 2つの案がありえることになる.
今度は,テーブルの分解の仕方を変える. 分解後のテーブルから,もとのテーブルに戻らない場合がある. このことを確認しておく.
create table C AS select distinct name, student_name from SCORE; create table D AS select distinct teacher_name, student_name, score from SCORE;
select * from C; select * from D;
テーブル C, D からは,テーブル SCORE を構築できない
SELECT C.name, D.teacher_name, C.student_name, D.score FROM C, D WHERE C.student_name = D.student_name;
次の問いに答えよ.その後,下記の解答例を確認せよ.
問い
次の PTABLE テーブルに関する問題
name | type | color ------------------------------ apple | fruit | red apple | fruit | blue rose | flower | white rose | flower | red rose | flower | yellow
SELECT DISTINCT name, type FROM PTABLE;
SELECT DISTINCT name FROM PTABLE;
SELECT E.name, E.type, F.color FROM E, F where E.name = F.name;
解答例
※ 問い合わせ結果は1つのテーブルになる.その属性名には,元のテーブル名と属性名をドットでつなげたドット記法を用いている.
select distinct name, type FROM PTABLE; name | type ------------------ apple | fruit rose | flower
select distinct name FROM PTABLE; name -------- apple rose
E name | type ------------------ apple | fruit rose | flower F name | color ------------------ apple | red apple | blue rose | white rose | red rose | yellow
name | type | color ------------------------------ apple | fruit | red apple | fruit | blue rose | flower | white rose | flower | red rose | flower | yellow