2016-06-08 66 views
1

使用CakePHP 3.x,我有3个模型:StudentProfile,Diploma1和Diploma2。多重匹配()和包含(),条件相关记录计数

  • StudentProfile的hasMany Diploma1
  • StudentProfile的hasMany Diploma2

Diploma1具有整数 “状态” 字段。

我需要得到哪些StudentProfiles:

  • 有相关的一个(或多个)Diploma1其中Diploma1.state = 2 或
  • 有一个(或多个)Diploma2(上Diploma2领域没有条件)

我需要用我的StudentProfiles检索匹配的Diploma1和Diploma2。

我使用搜索和分页程序组件,因此我必须使用一个查询来执行此操作。

现在,我心中已经能够做得到第一部分:

$query = $this->StudentProfiles 
    ->find('search', $this->StudentProfiles->filterParams($this->request->query)) 
    ->contain(['Diploma1' => function ($q) { 
     return $q->where(['Diploma1.state' => 2]); 
    }]) 
    ->matching('Diploma1', function($q) { 
     return $q->where(['Diploma1.state' => 2]); 
    }) 
    ->distinct(['StudentProfiles.id']) 
    ; 

    $this->set('studentProfiles', $this->paginate($query)); 

结合匹配和包含允许我补充的条件,并得到相关Diploma1(据我所知)。

现在我还需要得到所有StudentProfiles与相关Diploma2,这是我卡住的地方。如果我添加

->contain(['Diploma2']) 

...我的查询,我只得到Diploma2为具有匹配Diploma1(其中状态= 2),但我不明白,只有相关Diploma2 StudentProfiles StudentProfiles(不匹配Diploma1 ),这是完全正常的。

所以我有2个问题:

  • 我怎样才能有一个相关的Diploma2所有StudentProfiles(?即使用count(...)> 0,也许增加一个条件)
  • 我怎么能将此与条件(状态= 2)的匹配子句结合起来?

我希望这是明确的。 感谢

回答

0

稍微不同的方法,但也许它可以帮助

$query = $this->Profile->find(); 

$query->select([ 
    'Profile.id', 
    'Profile.name', 
    'D1.id', 
    'D1.name', 
    'D1.status', 
    'D1.profile_id', 
    'D2.id', 
    'D2.name', 
    'D2.status', 
    'D2.profile_id', 
    'd1c' => 'COUNT(D1.id)', 
    'd2c' => 'COUNT(D2.id)', 
]); 
$query->contain([ 
    'D1' => function($q) { 
     $q->where(['D1.status' => 2]); 
     return $q; 
    }, 
    'D2' 
]); 
$query->leftJoinWith('D1', function($q) { 
    return $q->where(['D1.status' => 2]); 
}); 
$query->leftJoinWith('D2', function($q) { 
    return $q; 
}); 
$query->having(function($q) { 
    return $q->or_([ 
     'd1c >' => 0, 
     'd2c >' => 0, 
    ]); 

}); 
$query->group('Profile.id'); 

我不能真正得到contain创建一个连接,所以我不得不添加这些leftJoinWith

+0

有趣,我给这是一个尝试尽快,谢谢! – Flo

+0

对我的第一次测试非常有用:),非常感谢这个“带蛋糕查询”的课程!我只是不明白为什么我们需要离开JoinWith和包含,但它的工作原理。 – Flo

+0

@Flo'包含'它像一个不同的范围,所以'主要查询'甚至不知道关于'contains'的数据,这就是为什么你需要使用'join'而不是'contains'。 –

相关问题