2012年2月27日月曜日

MySQL ぜひ覚えたい 関数 式 句 などの覚書(p181~)

『基礎からのMySQL』 西沢夢路著 (ソフトバンククリエイティブ) 
から得たぜひ覚えたい個所を列挙した。 Part3




(p182) 複数の抽出結果を合わせて表示する。
 ①select * from tb1 ; ②select * from tb2 ; の結果を
一度に表示させることを union で実現している。

select * from tb1 union seleect * from tb2 ;


これを見やすくする為、


(select * from tb1) union (select * from tb2) ;


なんて事もできる。



(p184) 3つ以上のテーブルから「union」で集める。

       (select * from tb where bang = 'A102')
union
       (select * from tb where bang = 'A103'
union   
       (select * from tb where bang = 'A104'
union
       (select * from tb where bang = 'A107') ;


と発行する事で、bang で抽出された4つの結果をまとめて
表示させる事ができる。


グループ化して表示させているように見える。


また、


select * from tb where bang not in ('A101') ;


というSQL文も紹介されている。 これは

テーブル内の bang が A101 以外を表示するもの。



select * from tb where in ('A101','A103',104'A','A107') ;

は、見慣れない SQL文 で戸惑ったが、

()内にあるものをグループとみなして、

そのグループに属するレコードの中から抽出するもの

ですね。





(p185) 条件を付けて複数の抽出結果を合わせて表示する。
 
 ① tb から uria が200以上のレコード持つ bang を抽出
 ② tb1 から tosi が35以上のレコード持つ bang を抽出


(select bang from tb where uria >= 200)
union
(select bang from tb1 where tosi >= 35) ;



結果は A101 , A102 , A105 の3件が抽出される。


2つのSQL文の結果を union はつなげて表示させている。


注意したいのが、

①の抽出結果は、A101 , A102 の2件であり、
②の抽出結果は、A101 , A105 の2件である。
合計 4件 が表示されるかと思いきや、
自動的に重複表示を制限しているのである。



重複表示を許す場合(純粋な OR 抽出?)は、

(select bang from tb where uria >= 200)
union all
(select bang from tb1 where tosi >= 35) ;



と、union に続けて all とすれば良い。



大量のデータを処理する場合は、union(重複を省く)では、

処理時間が長くなり、 union all(重複を許す)とすると、


処理時間が短くなる。らしい。




(p188) 複数のテーブルを結合して表示する(内部結合)。

 いよいよリレーショナルデータベース(以降RDB)らしい
内容になってきます。RDB = 複数テーブルを関連づける
という概念ですが、直前の union のところでも、2つのテーブル
(tb と tb1)を使って結果を表示していました。
ちょっと立ち止まり概念を整理したのですが、
union のところでは、2つのテーブルからの抽出結果を
ただ単に連続表示していただけでした。

内部結合 join 句 (※ INNER を指定すると、内部結合を「明示的」に指定できる。)は、
複数テーブルが共通に持つフィールドの値でテーブルを関連
づけ、実在するテーブル(tb , tb1)が持つ情報を、非実在の
テーブル(仮想テーブル)を作成し、それを表示している。

テキストでは、
select * 
    from tb 
join tb1
    on tb.bang = tb1.bang ;  

これは、 テーブル tb の bang と テーブル tb1 の bang が
同一であった場合に、それぞれのテーブルからレコードを
抽出し、全フィールドを結合して一件のレコードとして表示
するというものですね。
 
うまい表現ではないような気もしますが、
1レコード6フィールドの ハードディスクには実在しない
テーブル(仮想テーブル)を画面上に表示します。


内部結合 という事は、 外部結合 もある訳で、その違いを
把握しておきたいところですが、

テーブル tb には bang が A101、A102、A103、A104、A107 
の5種類、計10件のレコードが存在していて、
テーブル tb1 には bang が A101、A102、A103、A104、A105 
の5種類、計5件のレコードが存在している。


先の内部結合のSQL文では、9件のレコードが表示されたが、
bang が A107(tbだけにある) と A105(tb1だけにある) の
レコードは表示されなかった。 内部結合は、片方にしかない
情報は排除し、仮想テーブルには含めないのです。

それに対して、外部結合は片方にしかない情報も
仮想テーブルに 加えます。


    左のテーブル          右のテーブル
  bang   uria  tuki     bang   nama   tosi
  A103  101  4  |   A101   佐藤    40
  A102   54 54  |   A102   高橋    28
  A104  181  4  |   A103   中川    20
  A101  184  4  |   A104   渡辺    23
  A103   17  5  |   A105   西沢    35
  A101  300  5  |
  A102  205  6  |
  A104   93  5  |
  A103   12  6  |
  A107   87  6  |


左外部結合(left join) と 右外部結合(right join)。
inner join の inner を、left または right  に置き換えると、
左(右)外部結合の結果が得られます。

左外部結合とは、左のテーブル(tb)に 右(tb1)にはない
フィールド が存在する場合、そのデータも仮想テーブルに
加えてしまいます。違う言い方をすると、
左外部結合の結果は左テーブルのレコード総てを
仮想テーブルに加えて、右テーブルからは特定のキーに
よって一致するレコードを抽出し仮想テーブルに加える。
という事ですね。


(p194) using を使って on ~ の部分を見やすくする。
 テーブルを関係づけるために、
on tb.bang = tb1.bang (bang)というフィールドの内容が
同一かを判定させる。ここでは たまたま 2つのテーブルで
bang というフィールド名でしたが、
tb では、bang、 tb1 では bangou というフィールド名で
A101 やら A107 というデータを保持させていた場合、
「 on tb.bang = tb1.bangou 」 とすれば、テーブルどうしを
結合させられる。
using 句は、仮に2つのテーブルで、A101 やら A107 の
データを同じフィールド名で管理している場合、
join tb1 on tb.bang = tb1.bang を 
join tb1 using (bang) と簡単に記述できるというもの。




(p195)  
結合したテーブルから「where」で設定した条件で抽出する。
 結合した仮想テーブルから where 条件でレコードを抽出
する際は where句の条件では フィールド名だけではダメ。
必ずテーブル名を指定して MySQL に示してやる必要が
ある。

select tb . bang , tb1 . nama , tb . uria 
         from tb
join tb1
         using(bang)
where tb . uria >= 100




(p 197) たくさんのテーブルのデータを使って抽出する。
 テーブルの結合は2つ以上可能で仮に3つのテーブルを
結合する場合は、

select
       tb.bang,tb.uria,tb1.nama,tb3.ken
from
       tb
join
       tb1
using(bang)
join
       tb3
using(bang)
;
とする。




(p200) 
複数のテーブルの総てのレコードを表示する(外部結合)。
 内部結合(p188)後半の記述を参照。




MySQL ぜひ覚えたい 関数 式 句 などの覚書(Part1)へ

MySQL ぜひ覚えたい 関数 式 句 などの覚書(Part4)へ






情報処理再チャレンジブログ ホーム

0 件のコメント:

コメントを投稿