Recent Entries
Recent Comments
OZACC.blog: DB Category Archive

2010年1月12日

DB | 月初と月末の Timestamp

PostgreSQL で今日を基準に月初、月末の Timestamp を求める SQL。

-- 先月1日
select date_trunc('month', current_timestamp - interval '1 month');

-- 先月末日
select date_trunc('month', current_timestamp) - interval '1 day';

-- 今月1日
select date_trunc('month', current_timestamp);

-- 今月末日
select date_trunc('month', current_timestamp + interval '1 month') - interval '1 day';

ちなみに「interval」は省略可。

Posted by otsuka : 14:53 | Comment (0) | Trackback (0)

2009年12月 8日

DB | 一意な部分インデックス

部分インデックス
create table GIRL_FRIENDS (
    BOY_ID int,
    名前 text,
    本命 boolean,
    ...
);

上のような一夫多妻的な GIRL_FRIENDS テーブルがあったとして、ガールフレンドは何人いてもいいけど本命は一人だけという制約を課したい場合、今まではアプリケーション側だけで対応してたんだけど、部分インデックスに一意制約を加えれば PostgreSQL でもこの制約を課せることを今日知った。

この例の場合は次のようにインデックスを作る。

create unique index IDX_GIRL_FRIENDS on GIRL_FRIEND (BOY_ID) where 本命 = true;
Posted by otsuka : 11:31 | Comment (0) | Trackback (0)

2009年11月27日

DB | 範囲指定条件でのインデックス

PostgreSQL でのお話。単純な例に置き換える。

SELECT count(*) + 1 FROM 生徒 WHERE クラス = 'B組' AND 得点 > 80;

上の SQL 文は、テストの得点が 80 点の場合の B 組内での順位を求めるもの。

この生徒テーブルに (得点, クラス) の複合インデックスを張ってたんだけど、EXPLAIN 文で調べても上記の SQL 文でこのインデックスが使われてる気配がない。
おかしいな、PostgreSQL はバカだなあ、こんなの Oracle だったらテーブルスキャンすることもなくインデックスだけ見れば解決できそうじゃん。

でも、さっき自分が間違っていることに気付いた。

SELECT count(*) + 1 FROM 生徒 WHERE クラス = 'B組' AND 得点 = 80;

これならインデックスは使われる。が、実際の SQL は「得点 > 80」と、範囲を指定しているので、複合インデックスのキーは (クラス, 得点) という順になっていなければいけなかった。つまり、以下の SQL 文にインデックスを張るようなイメージで考えればよかった。

SELECT count(*) + 1 FROM 生徒 WHERE クラス = 'B組' ORDER BY 得点;
※この SQL は正しくないですよ。

複合インデックスの最初のキーに持ってくるのはカーディナリティが高いカラムであるべきという考えに縛られてしまってて気付かなかった。

さらに、指定する得点によってはインデックスが使われないケースも。そこで WHERE 句に条件を追加(得点は100点満点とする)。

SELECT count(*) + 1 FROM 生徒 WHERE クラス = 'B組' AND 得点 > 80 AND 得点 <= 100;

これで、EXPLAIN 文で調べていた限りではインデックスが使われるようになった。

Posted by otsuka : 01:11 | Comment (0) | Trackback (0)

2009年10月23日

DB | PostgreSQL to_char 関数の挙動

[pgsql-jp: 29417] Re: to_charの結果について
select '"' || to_char(1234, '00000') || '"';

上のSQLの結果は " 01234" になる(0 の前に半角スペースが入っている)。

select '"' || to_char(1234, 'FM00000') || '"';

このように FM 修飾子を付ければ、自分で想定していた "01234" という結果になった。

この修飾子については PostgreSQL ドキュメントの「日付/時刻書式用のテンプレートパターン修飾子」の表に載っているのだけど、数値型のテンプレートパターン修飾子は掲載されていないので気付かなかった(to_char の例には載っている)。

Posted by otsuka : 23:01 | Comment (0) | Trackback (0)

2009年8月29日

DB | PostgreSQL 8.4

PostgreSQL 8.4 の新機能 — Let's Postgres

もうリリースされて二ヶ月になるのか。全然知らなかった。

Window関数はすごい便利そう。ちゃんと見てないけど、Oracleのrank関数と同等の機能が使えるようになったってことでしょ。
row_number()の導入はようやく、といった感じ。

再帰SQLは難しい。使い道が分からない。

Posted by otsuka : 23:35 | Comment (0) | Trackback (0)

2009年5月 8日

DB | PostgreSQL ウォームスタンバイ

継続的アーカイブとポイントインタイムリカバリ(PITR)

PostgreSQLデータベースのウォームスタンバイの手段として初めてWALアーカイブとpg_standbyを使ってみた。これまでpg_dumpを使ったバックアップでのコールドスタンバイしかやったことなかったので。

WALアーカイブファイルはscpでスタンバイサーバにログシッピング。WALファイルの容量が結構大きかったので少し驚いたけど、pg_standbyの %r オプションによって、リストア後の古いWALファイルは自動的に削除されるようなので一安心。

archive_command、restore_commandの設定は今まで使ったことなかったし、ポイントインタイムリカバリについてもよく分かってなかったので、いろいろと勉強になった。

Posted by otsuka : 18:02 | Comment (0) | Trackback (0)

2009年2月27日

DB | .pgpass

パスワードファイル

cronとかからpg_dumpするときにパスワードを指定するにはどうしたらいいんだろうと調べていたら、こんなファイルがあることを知った。

今まで自分が管理するサーバでしかPostgreSQLを運用したことなかったので、スーパーユーザのpostgresユーザは認証ナシで各DBにアクセスできるように設定し、postgresユーザがバックアップを取るようにしていたから必要性がなかった。

Posted by otsuka : 19:53 | Comment (0) | Trackback (0)

2008年11月27日

DB | ランキングを求める

How to Optimize Rank Data in MySQL | O'Reilly Media

データベースに記録されたスコアを元にランキングを求める際の、パフォーマンスに秀でるテーブルやSQLの設計手法に関する記事。「High Performance MySQL」の著者によるもの。

サイト上で獲得点数のランキングを表示するゲームを作ったことがこれまでに何度もあるんだけど、リアルタイムで順位を求めることがほとんどだった。この記事の中で最もよくないとされる方法。まあ、MySQLではないのだけど。
あるスコアの順位を求めるには基本的に

SELECT count(*) FROM score WHERE score.score >= スコア;
というSQLになる。Oracleのようにrank()関数が使える場合は分からないけど、例えば上位50人のデータを順位付きで取得すると、SQLはひとつで済むけど結局サブクエリで順位を計算する形になるので、パフォーマンス的にはよくなさそうな気がする。
先頭レコードの順位だけ求めて、あとはプログラム側で順位を計算する方法もあるけど、この方法を採ったことはない。この方が速いのかなぁ。
数万くらいのレコード数ならインデックスをちゃんと張れば特に問題ないのだけど、サイトによってテーブル構成が異なるので、運用後にレコード数が増えてSQLの実行時間が遅くなってきてからインデックスやSQLを見直して解決している。

この記事では、更新コストは掛かっても順位カラムをテーブルに持たせておけ、count()は使うな(InnoDBは特にcount()が遅いので)という方針をより良い設計として挙げている。そして、更新のパフォーマンスを上げるためにMySQLのユーザ変数機能を使った順位の求め方を紹介している。それでも更新コストは比較的大きいので、得点更新時に毎回やるのではなく後でバッチ処理した方がいいんだけどねと、ちょろっと述べている。

今丁度、規模の大きめなランキングシステムをMySQL使って作る設計をしているので、いろいろと悩んでいる。運用後の変更は難しそうなので最初からバシッと決めたいところ。


MySQLのユーザ変数については、この記事を読んで初めて知った。他にどういう用途で使えるのかまだ分からないけど、面白そうな機能。
ハイパフォーマンスMySQL」も読んでおきたいのだけど、第1版は結構古いので第2版の原著を読むか。ここ一年くらい、洋書の原著を買っても読む余裕がなくて、さあ読もうとなると日本語版が出てたりする。

Posted by otsuka : 00:10 | Comment (1) | Trackback (0)

2008年4月18日

DB | SQLパズル

2-3-28 最小の空き番号を取得その2

誰かこれのMySQL(4.1)版を教えてください。

SELECT
    MIN(t0.No) + 1
FROM
    GetNo AS t0
    LEFT JOIN GetNo AS t1 ON t0.No + 1 = t1.No
WHERE
    t1.No IS NULL;

これだと1が抜けている場合にダメだ。

Posted by otsuka : 16:01 | Comment (1) | Trackback (0)

DB | GISとか幾何演算とか

Flashのステージ上の座標データをサーバサイドで処理したくてその方法を調べてたんだけど、GIS(Geographic Information System)という技術に行き着いた。名前だけは時々聞くことはあったけど、内容については全く知らないものだった。で、ざっと調べてみたけど、GISが示す範囲が大きくてやっぱりよく分かりませんでした。

OpenGISという仕様もあり、それを実装した(?)PostGISというPostgreSQLの拡張版もある。MySQLもOpenGISを実装している? うーん、理解しきれません。

そんなGISよりもPostgreSQLに標準で備わっている「幾何データ型」と「幾何関数と演算子」が一番使いやすいのではないかと思いました。
標準SQLにはない型なので、ORマッパーから扱えず、自前でSQLを書かないといけないのが面倒そうだけど。

幾何演算はDBではなくプログラムの中でもやりたいと思ったら、JGCLというJavaライブラリも発見。幾何と言うとFlashのflash.geomパッケージ位しか知らず、ほとんど未知の分野だったのでちょっと興味が湧いてきた。

Flashの座標データ処理はやっぱりFlashでやってもらうことにして、GISやら幾何ライブラリやらについて調べてみようと思いました。

Posted by otsuka : 03:03 | Comment (0) | Trackback (0)

2007年11月21日

DB | PostgreSQL 8.3

【特集】期待度大のバージョンアップ - PostgreSQL 8.3の改良点を徹底分析 | エンタープライズ | マイコミジャーナル

新機能てんこ盛りだ。
同期スキャン
ORDER BYの高速化
が普段使う上では一番役に立ちそう。ORDER BYの高速化はOFFSET付きの場合はダメとあるけど、「offset=0」が付いてしまってもダメなのかな?

全文検索機能の組み込みも今後使えるかも。

Posted by otsuka : 14:24 | Comment (0) | Trackback (0)

2007年7月23日

DB | Oracle NULLS FIRST

NULL の特性 - Oracle/オラクルをマスターするための基本と仕組み

NULL はデフォルトの昇順ソートでは最後、降順ソートでは最初に並び替えられる。(≒無限大)
ORDER BY のオプション指定により、その並び順を変更することができる。

NULLS FIRST
NULL 値を順序の最初にする
NULLS LAST
NULL 値を順序の最後にする
なんだよ、できるジャン。先に言ってくれよ。


このオプションの使い方を勘違いしていた。

ORDER BY ORDER_NO DESC NULLS FIRST
これだったら、NULL値がいなかるORDER_NOより小さくなって、DESCオーダーなのでORDER_NO=1のレコードより後ろに来ると思ってた。この場合実際は、ASC/DESCを問わずNULL値が行の最初に来る。

Posted by otsuka : 16:23 | Comment (0) | Trackback (0)

2007年7月19日

DB | Oracle MINUS演算子

SQL:EXCEPT,MINUS(集合演算子 差集合)について

EXCEPT演算子はPostgreSQL、DB2等で使用できます
MINUS演算子はOracleで使用できます

Oracleで差を求めるのはExceptではなくMinusだったのか。ひとつ学んだ。

Posted by otsuka : 18:21 | Comment (2) | Trackback (0)

2007年7月12日

DB, Java.Spring | PostgreSQL 8.2 RETURNING句

INSERT

省略可能なRETURNING句により、INSERTは実際に挿入された各行に基づいて計算された値を返すようになります。 これは、通番のシーケンス番号など、デフォルトで与えられた値を取り出す時にかなり便利です。 しかし、そのテーブルの列を使用した式を指定することができます。 RETURNINGリストの構文はSELECTの出力リストと同一です。

PostgreSQL 8.2から更新系のSQLで RETURNING 句がサポートされていて、これによってINSERT時にSERIAL型で割り振られたIDを返すことが可能になってました。例えば、
INSERT INTO emp(name, age) VALUES('あめちゃん', 1) RETURNING id;
というINSERT文は結果として
SELECT id FROM emp WHERE name='あめちゃん';
と同じ結果を返します。
他のDBでは専用の関数があったりするのですが、PostgreSQLでは更新系SQL文で一緒に結果を取得する形です。

今Springを使ってWebアプリを作ってるんだけど、ではどうやってこのID値を取得すればいいのだろうと悩みました。更新系は JdbcTemplate#update() を使うけど、このメソッドの戻り値は更新された行数であって RETURNING 句の値ではない。そもそも RETURNING 句はIDだけ返すわけではなく * を指定すれば全てのカラムが返ってくる。つまりINSERTとSELECTを順に一度に実行しているようなもの。なので、結論から言うと JdbcTemplate の場合は query() メソッドを使ってINSERT文を実行すればよい。RETURNING 句でIDだけを返すのなら、queryForInt() が最適。

Posted by otsuka : 16:31 | Comment (0) | Trackback (0)

2007年6月26日

DB | Oracle BYPASS_UJVCヒント

Oracle:Update時に、ORA-01779: キー保存されていない表にマップする列は変更できません のエラーが発生

SELECT項目に 「/*+ BYPASS_UJVC */」を入れることにより、エラーが発生しなくなる。

MEMO。

Oracleの細かいバージョンによっては使えない場合もあるので注意。

Posted by otsuka : 20:01 | Comment (0) | Trackback (0)

2007年5月22日

DB | Oracle 全テーブルの、レコード数を数える

Oracle Technology Network (OTN) Japan - 掲示板 : 全テーブルの、レコード数を数える方法 ...
select
   table_name,
   to_number(
     extractvalue(
       xmltype(
    dbms_xmlgen.getxml('select count(*) c from '||table_name))
       ,'/ROWSET/ROW/C')) count
 from user_tables
 WHERE TABLE_NAME NOT LIKE 'BIN$%'
   and (iot_type != 'IOT_OVERFLOW' or iot_type is null)
order by table_name
何がどうなってるのか分からないけど、MEMOっておく。
Posted by otsuka : 12:19 | Comment (0) | Trackback (0)

2006年8月 7日

DB | CASE式のススメ

プログラミングと開発者のためのCodeZine:CASE式のススメ(前編)(データベース, SQL, CASE)

このトリックの重宝するところは、SQLの結果を二次元表の形に整形できることです。

最近は自分でもCASE句を使う機会が多いのだけど、group byでまで使えるとは思ってなかった。

これを含めミックさんのSQL記事は勉強になった。

Posted by otsuka : 22:41 | Comment (0) | Trackback (0)

2006年4月25日

DB | generate_series関数

集合を返す関数

今日初めて知ったPostgreSQLの関数。8.0から導入されたのかな。
むちゃむちゃ便利。

この関数だけで連続した数値のテーブルを表現することができる。他のテーブルと結合して使う場合は、

generate_series(0, 10) as s(n) left outer join other_table t1 on (s.n = t1.column)
のように、生成数値はsテーブルのnカラムにあるものと別名定義する。

Posted by otsuka : 02:43 | Comment (0) | Trackback (0)

2006年4月24日

DB | 度数分布

4 章 データの代表値

度数分布のヒストグラムを描くために、SQLで度数分布テーブルを引っ張り出してきたいのだけど、これがなかなか難しい。基本系のSQLはコレ。

select
 floor(得点 / 階級幅) * 階級幅 as 得点の範囲,
 count(*) as 度数
from
 生徒
group by
 1
order by
 得点の範囲
そして階級数を元に階級の幅を動的に算出して度数を求めようと、SQLがどんどん複雑になってしまった。今日はかなり頭を使ったと思う。そんなこんなで、何とか対象データから動的に階級幅を設定して、その度数を求めるSQLを作ることはできた。

一般に度数分布テーブルはどうやって求めるのだろう? データベースからプログラムに全生徒の得点レコードを取り込んでしまえば、多少複雑な計算もできるだろうけど、全レコードを取り込むコストを想像するとスマートなやり方じゃないような気がする。
となると、やっぱりSQL一発でやるものなのか。うーむ。

今日作ったSQLでは階級幅が「(データの最大値-最小値) / 階級数」をベースとしているため、飛び抜けて大きい値があるデータの場合、あまり役に立たない階級幅の度数分布テーブルになってしまう。メディアンは算出できるけど、それが分かったところで最適な階級幅は求められそうもない。標準偏差とか使うのかなあ? 標準偏差ってやつが何なのか理解できてないのだけど・・・

Posted by otsuka : 04:36 | Comment (0) | Trackback (0)

2006年4月19日

DB | 順位から得点を取得するSQL

テストの得点から順位を算出するような場合、下記のようなSQLが一般的。
SELECT
    count(*) as 順位
FROM
    生徒
WHERE
    得点 >= {得点}
SELECT
    count(*) as 順位
FROM
    生徒
WHERE
    得点 >= (SELECT
                得点
            FROM
                生徒
            WHERE
                生徒ID = {生徒ID}
            )
が、じゃあ逆に順位から得点を、となった時にふと悩んでしまった。すぐに分かったけど、一応メモしておく。Postgresの場合。
SELECT
    得点
FROM
    生徒
ORDER BY
    得点 desc limit 1 offset {順位} - 1
存在しない順位(2位の人が二人いた場合、3位はない)が指定された場合に微妙なことになるなあ。
Posted by otsuka : 22:12 | Comment (0) | Trackback (0)

2006年1月18日

DB | Oracle ランダムソート

ワンポイント

select * from [社員マスタ] order by dbms_random.random()

MEMO。

Posted by otsuka : 11:34 | Comment (0) | Trackback (0)

2006年1月16日

DB | PostgreSQL - NULLの存在する列の逆順ソート

[pgsql-jp: 31790] Re: NULLの存在する列の逆順ソート

select num from hoge order by num is null, num desc;

MEMO。

Posted by otsuka : 17:05 | Comment (0) | Trackback (0)

2005年11月18日

DB | Oracleと8080番ポート

Tomcat が起動しない場合の対処方法 @みっちーわーるど

CONNECT SYSTEM/XXXXX@YYYYY AS SYSDBA ←XXXXX はSYSTEMのパスワード、YYYYYは接続文字列です
SET ECHO ON
SPOOL CATNOQM
@D:\oracle\ora92\rdbms\admin\catnoqm.sql ←実際のOracleのパスになおして下さい
SPOOL OFF
DROP TABLESPACE XDB INCLUDING CONTENTS AND DATAFILES;
SHUTDOWN IMMEDIATE
STARTUP

先日インストールしたOracle 9iが8080番ポートを占領しているので、何とかしたいと思って調べてみたら、どうやらXMLデータベースがこのポートを使用しているらしい。XMLデータベースなんて使ってないしー、ということで上記ページに削除方法が出てたので、バッサリ削除した。

Posted by otsuka : 19:02 | Comment (0) | Trackback (0)

2005年8月30日

DB | PostgreSQL8.0のJDBCドライバを7.4.x互換モードで使う

Heretic Programmer(2005-08-30)

jdbc:postgresql://localhost/testdb?protocolVersion=2

MEMO。

Posted by otsuka : 11:53 | Comment (0) | Trackback (0)

2005年3月20日

DB | SQL - IS NOT FALSE

SQL質疑応答スレ Part 2

via はぶにっきのコメント

こんなSQLは初めて見た。後でよく調べてみよう。

http://arton.no-ip.info/collabo/backyard/?PreparedStatementAndNull

Posted by otsuka : 19:30 | Comment (0) | Trackback (0)

2005年2月23日

2004年11月21日

DB | Postgres UNIQUE制約の延期

CREATE TABLE

DEFERRABLE
NOT DEFERRABLE

これは制約を延期させることが可能かどうかを制御します。 延期させられない制約は各コマンドの後すぐに検査されます。 延期可能な制約の検査は (SET CONSTRAINTS コマンドを使用して)トランザクションの終了時まで延期することができます。 NOT DEFERRABLE がデフォルトです。 現在、外部キー制約のみがこの句を受け付けることができます。他の種類の全ての制約は延期させられません。

ユニーク制約の延期はできないのかあ。むぅ。DBでの制約ではなく、アプリケーション側でユニークを保証するしかないか。

Posted by otsuka : 20:07 | Comment (0) | Trackback (0)

2004年11月16日

DB | coalesce

coalesce

coalesce /kòHəlés | kNH-/
━ 【動】【自】
Ⅰ 〈折れた骨が〉癒合(ゆごう)する.
Ⅱ 合体する; 合同[連合]する.
語源
ラテン語「共に生育する, 堅固になる」の意; coalition と同語源

New College English-Japanese Dictionary, 6th edition (C) Kenkyusha Ltd. 1967,1994,1998

今日も読めない単語をひとつ。SQLで出てきます。「COALESCE関数は、NULLでない自身の最初の引数を返します。」

読めないので、きっと余り使われていない関数だと勝手に予想しています。僕の耳で聞いた音をカタカナに直すと「コゥアレス」です。アクセントは「レ」です。「コアス」と読んでれば笑われることはなさそうです。

最後の"ce"に惑わされて、いつも読み方を忘れてしまっていましたが、きっと今日からは大丈夫。読めることが嬉しくって無駄に複雑なSQLを書いてしまいそうです。

Posted by otsuka : 23:08 | Comment (0) | Trackback (0)

2004年9月 1日

DB | Postgres 日付演算

PostgreSQL 編16 - 日付計算、曜日、月末日、時間計算、期間計算、日付抽出 - SAK Streets

■日の演算(日加算、日減算) ・うるう年や大の月、小の月も考えなくて良い。
select current_timestamp + '1 days';

PostgreSQLでの日付演算の方法。

Posted by otsuka : 01:57 | Comment (0) | Trackback (0)

2004年8月 5日

DB | Windows PostgreSQL

PgFoundry: Project Info- PostgreSQL installer

via とらねこ放浪記

WindowsネイティブなPostgreSQL。これがあるなら、もうCygwinを使う理由の半分以上はなくなる。

Posted by otsuka : 16:47 | Comment (0) | Trackback (0)

2004年2月17日

DB | 今日のSQL

select * from table_name order by random()
これでランダムに行を取得できる。(PostgreSQL。他のDBは分からない。)

何故だ。この挙動が理解できない・・・ random()が返すのは0.0~1.0の値のはず。order by 0.5だとエラーになるし。

Posted by otsuka : 04:06 | Comment (4) | Trackback (0)

2004年2月10日

Book, DB | PostgreSQL全機能リファレンス

最近買った本。カスタマーレビューが五つ星だけあって、良書。ドキュメントを読んでるだけでは気づかないことや分からないことが詳しく解説されていてます。

今回のプロジェクトでは大活躍。知っていることも、敢えてもう一度この本で調べなおす。すると新たな発見があったり。そんな一冊です。


おぅ、もう朝だ。

Posted by otsuka : 05:59 | Comment (0) | Trackback (0)

DB | EAのPostgreSQLデータ型

EA 3.6にデフォルトで定義されているものだけだと必要なデータ型が抜けてたので、いくつか型を追加した。
postgresql.xml

EAのベストプラクティスの一つは、よく使う型やパッケージ構成を設定した独自のBase.EAPを作成して、新規プロジェクト生成時に参照プロジェクトに指定すること。

Posted by otsuka : 05:51 | Comment (0) | Trackback (0)

2004年2月 3日

DB | 今日のSQL

int[] ids = new int[] { 1, 2, 3 };
PreparedStatement pstmt = conn.prepareStatement(
  "SELECT * FROM item WHERE item_id IN (?)");
pstmt.setIntArray(1, ids);
...
こんな風にPreparedStatementが書ければいいのに。
Posted by otsuka : 18:54 | Comment (0) | Trackback (0)

2004年2月 2日

DB | 今日のSQL

DELETE FROM
    link
WHERE
    (dest, src) = (SELECT
                        src,
                        dest
                    FROM
                        link
                    WHERE
                        link_id = ?
                    ) OR
    link_id = ?;
今日書いたSQL。ある一方向のリンク(ID)を指定し、それと逆方向のリンクも一緒に削除する。

我ながらカッコイイSQL文だ。HQLじゃ書けまい!! (ホントか?)

Posted by otsuka : 22:10 | Comment (0) | Trackback (0)

2004年1月26日

DB | PostgreSQL bigintのインデックス

インデックスが付けられたsmallintあるいはbigintの列がテーブルにある場合、システムがそのインデックスを使用しようとした時に問題を引き起こすことがあります。例えば句が次のような形式の場合、

... WHERE smallint_column = 42

システムはインデックスを使用しません。

検索で使用する主キーとかはsmallintやbigintで持つなってこと? 知らんかった。

Posted by otsuka : 01:32 | Comment (0) | Trackback (0)

2004年1月11日

DB | The Effective Use of Joins in Select Statements

後で読むべし。

Posted by otsuka : 06:46 | Trackback (0)