久々、というかほとんど始めて技術的なことを書きます^^;
技術系に興味ない人は読み飛ばしてくださいね。
『よこほくネット』では一部にsymfonyと呼ばれるPHPのフレームワークを用いて構築を行っています。
symfonyによるDBアクセスはPropelというORMを使用するのですが、こいつにちょっとはまってました。
Aテーブルに、Bテーブルのキーを持つ可能性のあるカラムが3つほどあったとします。
発行したいSQLはこんなイメージです。
SELECT
A.*,b1.*,b2.*,b3*
FROM
A
LEFT OUTER JOIN B b1 ON A.b_id1 = B.id
LEFT OUTER JOIN B b2 ON A.b_id2 = B.id
LEFT OUTER JOIN B b3 ON A.b_id3 = B.id
で、こいつをなんとかPropelで実現させようとしたのですが、最初につまずいたのが
・Bに対する別名、『b1』『b2』『b3』のつけ方がよく分からない
これはこのサイトを参考に解決しました。
APeer::addSelectColumns($c);
BPeer::addSelectColumns($c);
BPeer::addSelectColumns($c);
BPeer::addSelectColumns($c);$c->addAlias( 'b1', BPeer::TABLE_NAME );
$c->addAlias( 'b2', BPeer::TABLE_NAME );
$c->addAlias( 'b3', BPeer::TABLE_NAME );$c->addJoin(APeer::B_ID1, BPeer::alias('b1', BPeer::ID), Criteria::LEFT_JOIN );
$c->addJoin(APeer::B_ID2, BPeer::alias('b2', BPeer::ID), Criteria::LEFT_JOIN );
$c->addJoin(APeer::B_ID3, BPeer::alias('b3', BPeer::ID), Criteria::LEFT_JOIN );
これで解決!・・・と思いきや、なんか予期しない結果が返ってきます。よくよく調べてみると、発行しているSQLが下記のようになっていました。
SELECT
A.*,B.*,B.*,B.*
FROM
(A, B)
LEFT OUTER JOIN B b1 ON A.b_id1 = B.id
LEFT OUTER JOIN B b2 ON A.b_id2 = B.id
LEFT OUTER JOIN B b3 ON A.b_id3 = B.id
SELECTされるカラムの名前が別名のb1,b2,b3になっていません。この結果、A表とB表の直積になってしまい、大量の行が選択されてしまいました。
問題があるのは『BPeer::addSelectColumns($c);』の部分。これを調べていくと…
あ…
ありました…
addSelectColumns with alias?
『Yes, you’re right — this doesn’t exist yet. 』
(´・ω・`)
どうやらPropelでは出来ないようです…
(長々書いて出来ない落ちでスイマセン…)