不要问为什么,但我有这种情况。
ActiveRecord Transport,Company,TransportDetail和TransportRow与Yii经典strutture(BELONG_TO,HAS_MANY等...)相关
不幸的是,由于基于fromTypeId值的条件连接(有一个toTypeId列),区域,城市和省份无法自动与TransportDetails相关。
不幸的是,我必须使用自由文本字段搜索TransportRow,该字段必须在LIKE中搜索以下字段: " company.name" (简单,与yii关系) " region.name或city.name或province.name基于列"
的值为了达到CompanyName并且通常加入每一个关联,我使用"与" sintax
$criteria->with = array('transportDetail','transportDetail.transport','transportDetail.transport.company');
使用此自动联接,在OR中使用company.name进行搜索我将基准条件与OR条件合并:
$criteriaORCompany = new CDbCriteria();
$criteriaORCompany->compare('company.name',$searchFilter->name,true,'OR');
$criteria->mergeWith($criteriaORCompany);
这项工作非常完美。
现在我必须扩展搜索范围。
此查询工作正常,但我不知道如何在Yii上重现它。如果将连接添加到其他三个表(城市,省和区域)以及where条件强制仅在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'))
我试图在Yii中复制此连接,手动添加连接但mergWith在关联连接之前发生
$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');
我尝试过将mergeWith放在一起但是它没有工作:
$criteria->with = array('transportDetail','transportDetail.transport','transportDetail.transport.company');
$criteria->mergeWith($criteriaLIKE);
错误很简单。由于区域和省份在其他区域之前加入,因此SQL无法在ON条件下找到该列,因为它已经拥有,但是在它们之后加入了一个tabled。
很抱歉很长的帖子。
任何建议?
答案 0 :(得分:0)
我找到了一个很好的解决方案。 首先,在广告显式JOIN之后,将始终添加具有自动化功能的>。 所以作为第一步,我在简单的JOIN中翻译了WITH,然后用LEFT OUTER JOINED ALL三个表
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。 三个外部表中只有一个会添加一些字符串,因为另外两个连接将返回NULL(由于LEFT JOIN)。
因此,如果一行为CITY,我将拥有" ROME + null + null" => " ROME +'' +''" => " ROME"
有了这个,我还可以使用allFrom和allTo列订购GridView。
下一步是使用此查询创建一个视图,直接连接主表。
再见!