2017-02-02 86 views
0

不要问为什么,但我有这样的表情。Yii - 喜欢条件加入

enter image description here

ActiveRecord的运输公司,TransportDetail和TransportRow与Yii的经典strutture(BELONG_TO,HAS_MANY等...)相关

Unfortunaly,区域,城市和省份不能自动关联由于基于fromTypeId值的条件连接而生成TransportDetails(有toTypeId列)。

Unfortunally我要搜索TransportRow与有类似下面的字段进行搜索的自由文本字段: “company.name”(易与警予的关系) “region.name或city.name或省。名称基于列的值”

为了达到公司名称,一般每一起releation,进出口使用‘与’sintax

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

有了这个自动加入,通过company.name在OR我合并搜索具有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条件中找到该列,因为拥有这些列,但后来加入了一张表。

对不起,对于很长的文章。

有什么建议吗?

+0

您需要咨询?修复架构/模型。那么你不需要问这个问题,因为你没有问题。你可能会感觉到,当你必须这样做的时候,这一天将会到来,所以今天这一天可能就是今天。 – Bohemian

+0

我无法触摸数据库或模型。 – MrMime

+0

您可以向您的主管提出这样的工作,解释当前的数据库/模型已损坏,除非完成,否则进一步的功能增强将非常困难。请参阅[技术债务](https://en.m.wikipedia.org/wiki/Technical_debt)了解您的情况的完整描述。 – Bohemian

回答

0

我找到了一个很好的解决方案。 首先,在广告显式加入后,总是会添加 - >自动化功能。 因此作为第一步,我翻译的,在简单连接,然后参加了所有三个表与LEFT OUTER

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)。

因此,如果行的城市,我都会有“罗马+空+空” =>“罗马+‘’+‘’” =>“罗马”

有了这个,我也可以订购使用的GridView allFrom和allTo列。

下一步是使用此查询创建视图直接连接主表。

再见!