2017-02-02 9 views
0

なぜか、私はこのテーブルの状況を尋ねません。Yii - 条件付き参加のLIKE

enter image description here

ActiveRecordの交通、会社、TransportDetailとTransportRowがYiiの古典struttureと関連している(BELONG_TO、HAS_MANY等...)

Unfortunaly、地域、都市と州は、自動的に関連することはできませんtoTypeIdの値に基づいて調整された結合(toTypeId列が存在するため)によって、TransportDetailsに変換されます。

Unfortunally私は、次のフィールドなどに検索する必要がフリーテキストフィールドでTransportRowを検索する必要があります(Yiiの関係で簡単に、) 「company.name」 「region.nameまたはcity.nameまたは県。 「仕入に到達し、一般的に使用するすべてのreleation、イムに参加するには

『マージにcompany.nameで検索する、sintaxこの自動加入して

$criteria->with = array('transportDetail','transportDetail.transport','transportDetail.transport.company'); 

』とOR I列の値に基づいて、名前を付けますOR基準のベース基準:

$criteriaORCompany = new CDbCriteria(); 
$criteriaORCompany->compare('company.name',$searchFilter->name,true,'OR'); 
$criteria->mergeWith($criteriaORCompany); 

これは完全に機能します。

今、私は検索を拡張する必要があります。

このクエリは正常に機能していますが、私はYiiでそれを再現することはできません。あなたは罰金値を使用するために、他の3つのテーブル(都市、州および地域)に、どこで、条件力に参加typeColumnが正しい値を持っている場合にのみ、検索作業を追加する場合:

[ other join ...] 
LEFT OUTER JOIN regions cr on (cr.id = transportDetail.fromId) 
LEFT OUTER JOIN provinces cp on (cp.id = transportDetail.fromId) 
WHERE ((cr.name LIKE '%TEST%' and toTypeId = 'REGION') 
OR (cp.name LIKE '%TEST%' and toTypeId = 'PROVINCE')) 

私はしました

$criteria->with = array('transportDetail','transportDetail.transport','transportDetail.transport.company'); 
$criteria->mergeWith($criteriaLIKE); 

エラー:これはは、参加が、関係は、私はと後mergeWithを置くことを試みたが、それは動作しません

$criteriaLIKE = new CDbCriteria; 
$crt = Region::model()->tableName(); 
$cpt = Province::model()->tableName(); 
$criteriaLIKE->join .= 'LEFT OUTER JOIN '.$crt.' cr on (cr.id = transportDetail.fromId)'; 
$criteriaLIKE->join .= 'LEFT OUTER JOIN '.$cpt.' cp on (cp.id = transportDetail.fromId)'; 
$criteriaLIKE->addCondition("cr.name LIKE '%probe%' and toTypeId = 'REGION'",'OR'); 
$criteriaLIKE->addCondition("cp.name LIKE '%probe%' and toTypeId = 'PROVINCE'",'OR'); 

に参加する前にmergWithが起こる手動で追加のYiiに参加複製しようとしました単純です。リージョンと州が他のフィールドの前に結合されていると、所有されているが列の後に結合された表があるため、SQLは列をON条件で見つけることができません。

長いポストに申し訳ありません。

アドバイスはありますか?

+0

アドバイスが必要ですか?スキーマ/モデルを修正してください。あなたは問題がないので、この質問をする必要はありません。あなたはおそらく今日はそうかもしれないように、あなたはそれをやらなければならない時が来ていると思います。 – Bohemian

+0

DBやモデルに触れられません。 – MrMime

+0

あなたはスーパーバイザーにそのような仕事を提案し、現行のDB /モデルが壊れていることを説明することができます。あなたの状況の完全な説明については、[Technical debt](https://en.m.wikipedia.org/wiki/Technical_debt)を参照してください。 – Bohemian

答えて

0

私は良い解決策を見つけました。 まず、広告の明示的なJOINの後に、自動化された - >が常に追加されます。 だから、最初のステップとして、私はJOINのシンプルでWITHを翻訳した後、LEFT OUTERを持つすべての3つのテーブルに参加した

The criteria is used on transportRows ActiveRecord 

$criteria->join = " JOIN ".TransportDetail::MODEL()->tableName()." detail ON (detail.id = t.transportDetailId)"; 
    $criteria->join .= " JOIN ".Transport::MODEL()->tableName()." transport ON (transport.id = detail.transporttransportId)"; 
    $criteria->join .= " JOIN ".Company::MODEL()->tableName()." company ON (company.id = transport.companyId)"; 

    $criteria->join .= " LEFT JOIN ".City::model()->tableName()." cityFrom ON (cityFrom.id = detail.fromId AND detail.fromTypeId = 'CITY')"; 
    $criteria->join .= " LEFT JOIN ".City::model()->tableName()." cityTo ON (cityTo.id = detail.toId AND detail.toTypeId = 'CITY')"; 

    $criteria->join .= " LEFT JOIN ".Region::model()->tableName()." regionFrom ON (regionFrom.id = detail.fromId AND detail.fromTypeId = 'REGION')"; 
    $criteria->join .= " LEFT JOIN ".Region::model()->tableName()." regionTo ON (regionTo.id = detail.toId AND detail.toTypeId = 'REGION')"; 

    $criteria->join .= " LEFT JOIN ".Province::model()->tableName()." provinceFrom ON (provinceFrom.id = detail.fromId AND detail.fromTypeId = 'PROVINCE')"; 
    $criteria->join .= " LEFT JOIN ".Province::model()->tableName()." provinceTo ON (provinceTo.id = detail.toId AND detail.toTypeId = 'PROVINCE')"; 

    $criteria->select = "t.*, 
         CONCAT(IFNULL(locCompanyFrom.name,''),IFNULL(regionFrom.name,''),IFNULL(provinceFrom.name,'')) as allFrom, 
         CONCAT(IFNULL(locCompanyTo.name,''),IFNULL(regionTo.name,''),IFNULL(provinceTo.name,'')) as allTo"; 

キーは、選択にCONCATとIFNULLです。 他の2つの結合が(LEFT JOINのため)NULLを戻すため、3つの外部表のうちの1つのみがいくつかのストリングを追加します。

CITYなどの行のであれば、私は "ROME +ヌル+ヌル" => "ROME + '' + ''" => "ROME" 私もallFromを使用するGridViewを注文することができます。これにより

を持っていますおよびallTo列。

次の手順は、このクエリを使用してメインテーブルに直接結合するビューを作成することです。

Bye!