骨のダイスを転がそう
2010-06-02
_ [Ruby] Jruby 1.5 で、readline のプロンプトが化ける。
Windows上でのこと。
require "readline"
require "iconv"
i = Iconv.iconv("Shift_JIS","UTF-8","ぷろんぷと>")
while buf = Readline.readline(i , true)
print "-> ", buf, "\n"
end
とやっても、プロンプトが化けてしまう。そもそも、jrubyのreadlineって、裏側でなにを使っているんだろうか?
_ [SQL] 自己非等値結合の意味が分かった!
ミックさん (というと最近、どうしても仮面ライダーWのことを連想してしまうが) のページで書かれていた自己非等値結合、マスターしたいなーと思いつつ、イメージがつかめずにいた。同心円ってなんだろう。とか。
同心円、というよりも、正方形を半分に切った直角三角形をイメージした方が理解しやすかった。そして、やはり実際にSQLを動かしてみないと、なかなかイメージが湧かなかった。手を動かすのって大事だわ。
| 名前 | 給料 |
| A さん | 100 |
| B さん | 200 |
| C さん | 300 |
| D さん | 400 |
| E さん | 500 |
| F さん | 600 |
とゆーテーブルがあったとして、これを単純にT1、T2 という名前で自己結合すると、
SELECT * FROM T1,T2
| T2 A さん | T2 B さん | T2 C さん | T2 D さん | T2 E さん | T2 F さん | |
| T1 A さん | T1 100,T2 100 | T1 200,T2 100 | T1 300,T2 100 | T1 400,T2 100 | T1 500,T2 100 | T1 600,T2 100 |
| T1 B さん | T1 100,T2 200 | T1 200,T2 200 | T1 300,T2 200 | T1 400,T2 200 | T1 500,T2 200 | T1 600,T2 200 |
| T1 C さん | T1 100,T2 300 | T1 200,T2 300 | T1 300,T2 300 | T1 400,T2 300 | T1 500,T2 300 | T1 600,T2 300 |
| T1 D さん | T1 100,T2 400 | T1 200,T2 400 | T1 300,T2 400 | T1 400,T2 400 | T1 500,T2 400 | T1 600,T2 400 |
| T1 E さん | T1 100,T2 500 | T1 200,T2 500 | T1 300,T2 500 | T1 400,T2 500 | T1 500,T2 500 | T1 600,T2 500 |
| T1 F さん | T1 100,T2 600 | T1 200,T2 600 | T1 300,T2 600 | T1 400,T2 600 | T1 500,T2 600 | T1 600,T2 600 |
こんな感じの集合ができあがる。これは、SQL のテーブルではなくて、1マス1マスが、テーブルの行にあたる集合だ。
で、
SELECT * FROM T1,T2 WHERE T1.給料 => T2.給料
とすると、条件に合致するのは、
| T2 A さん | T2 B さん | T2 C さん | T2 D さん | T2 E さん | T2 F さん | |
| T1 A さん | T1 100,T2 100 | T1 200,T2 100 | T1 300,T2 100 | T1 400,T2 100 | T1 500,T2 100 | T1 600,T2 100 |
| T1 B さん | T1 200,T2 200 | T1 300,T2 200 | T1 400,T2 200 | T1 500,T2 200 | T1 600,T2 200 | |
| T1 C さん | T1 300,T2 300 | T1 400,T2 300 | T1 500,T2 300 | T1 600,T2 300 | ||
| T1 D さん | T1 400,T2 400 | T1 500,T2 400 | T1 600,T2 400 | |||
| T1 E さん | T1 500,T2 500 | T1 600,T2 500 | ||||
| T1 F さん | T1 600,T2 600 |
こんだけ。
SELECT MIN(T1.給料),COUNT(T1.給料) FROM T1,T2 WHERE T1.給料 => T2.給料 GROUP BY T2.給料
| T2 A さん | T2 B さん | T2 C さん | T2 D さん | T2 E さん | T2 F さん | COUNT(T1.給料) | |
| T1 A さん | T1 100,T2 100 | T1 200,T2 100 | T1 300,T2 100 | T1 400,T2 100 | T1 500,T2 100 | T1 600,T2 100 | 6 |
| T1 B さん | T1 200,T2 200 | T1 300,T2 200 | T1 400,T2 200 | T1 500,T2 200 | T1 600,T2 200 | 5 | |
| T1 C さん | T1 300,T2 300 | T1 400,T2 300 | T1 500,T2 300 | T1 600,T2 300 | 4 | ||
| T1 D さん | T1 400,T2 400 | T1 500,T2 400 | T1 600,T2 400 | 3 | |||
| T1 E さん | T1 500,T2 500 | T1 600,T2 500 | 2 | ||||
| T1 F さん | T1 600,T2 600 | 1 |
あとは、HAVING で、何個の要素を持っているか、を限定すれば良い。
で、あらためて見ると、ミックさんのページの図も同心円、と言いつつ、正方形を分割した直角三角形に見える。
ここではスペースの都合で書けないけど、1つのテーブルの中で、部分集合ごとの上位n位、というのも、これの応用で取り出せる。単純な自己結合のあとで、条件を絞っていくようにするとイメージを掴みやすい。ああスッキリ。
[ツッコミを入れる]