查询以找到cakephp中关联模型(有很多)的位置为空

时间:2014-06-27 15:38:37

标签: mysql sql cakephp

我有一个名为Application的模型。 Application与名为has_many的{​​{1}}模型相关联。

Location有很多Application

在我的应用程序查询中:

Location

我发现$this->Application->find('all', array('conditions' => 'Application.status' => 'accepted')); applicationsstatus。{/ p>

我想要实现的下一件事是查找关联accepted为空/空的Application条记录,或者换句话说Locationcount条为0的记录

我试图像这样进行Location查询:

join

但似乎只是在查询 $join_query = array( 'table' => 'locations', 'alias' => 'Location', 'type' => 'INNER', 'conditions' => array( 'Location.application_id = Application.id', 'OR' => array( array('Location.id' => NULL) ) ) ); 条记录,这些记录确实有相关的Application条记录。

如果你们有任何想法,请先谢谢。

3 个答案:

答案 0 :(得分:2)

您需要使用左连接,而不是内连接。内部联接将仅获得在您要加入的两个表中都有一行的结果,其中您只需要左表中只有一行的结果。左连接将在左表中获得所有结果,无论右表中是否有与之关联的行。然后在连接完成后添加一个条件,以仅选择其中Location.id为null的连接结果。

$this->Application->find('all',
    array(
        'conditions' => array('Location.id' => null),
        'joins' => array(
             array(
                'table' => 'locations',
                'alias' => 'Location',
                'type' => 'LEFT',
                'conditions' => array('Location.application_id = Application.id')
             ),
         ),
    )
);   

答案 1 :(得分:0)

您的查询显示“使用application_id = id,AND(1 OR where where location.id = null)”查找任何应用程序及其位置,以便匹配任何具有位置的应用程序。

我要做的是离开联接,只使用可包含和计数。使用普通的SQL我会使用左连接并计算Locations,就像在this example中一样。但是蛋糕在没有命名列的情况下表现不佳,比如“COUNT(*)AS num_locations”,所以我倾向于避免这种情况。

我将您的查询转换为可包含的

$apps = this->Application->find('all', array('contains'=>'Location'));
foreach($apps as $app) {
    if (count($app['Location']) <= 0)
        //delete record
}

您还可以实现counterCache,并在BD列中保留每个应用程序的位置数,因此查询可以是一个简单的查找

$this->Application->find('all', array('conditions'=>array('location_count'=>0)));

Ooooor,您可以添加virtual field“SUM(*)作为num_locations”,然后使用“left outter join”连接并在条​​件上比较“num_locations = 0”。

这些是我想到的选择。我个人会使用第一个,如果查询将是一次/不是很常用的查询。可能把它放在应用程序模型中,如

 public function findAppsWithNoLocations() {
    $apps = this->Application->find('all', array('contains'=>'Location'));
    foreach($apps as $app) {
        if (count($app['Location']) <= 0)
            //delete record
    }
 }

但如果每个应用的位置总和将是您要搜索的周期性查询,则其他两个选项会更好。

修改

当然,Kai的答案选项可以满足您的需求xD。这种使事情复杂化的倾向将是我的结束......好吧,这里将留下答案以显示对其他复杂选项的引用(特别是如果你需要多次计算关系的话,也可以使用counterCache)。

答案 2 :(得分:0)

我知道这已经是一段时间了。 我可以这样管理它:

public function getEmpty($assoc) {

    foreach($this->find('all') as $c){

        if(empty($c[$assoc])) $return[] = $c;

    }
    return $return;
}

现在我获得了所有具有空关联数据的条目。

在我的控制器中我调用这样的函数:

$ce = $this->Company->getEmpty('CompaniesUsers');

公司用户是我想检查的空关联模型。