多个匹配()和contains(),相关记录的条件计数

时间:2016-06-08 10:16:12

标签: cakephp cakephp-3.0

使用CakePHP 3.x,我有3个模型:StudentProfile,Diploma1和Diploma2。

  • StudentProfile拥有多个Diploma1
  • StudentProfile hasMany Diploma2

Diploma1有一个整数"州"字段。

我需要获得StudentProfiles:

  • 有一个(或多个)相关的Diploma1,其中Diploma1.state = 2 OR
  • 拥有一个(或多个)Diploma2(Diploma2领域无条件)

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

我使用的是Search and Paginator组件,因此我必须使用一个查询执行此操作。

目前,我已经能够通过以下方式获得第一部分:

$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(据我所知)。

现在我需要获得所有带有相关Diploma2的StudentProfiles,这就是我被困住的地方。如果我添加

->contain(['Diploma2'])

...对于我的查询,我只获得了具有匹配的Diploma1(其中state = 2)的StudentProfiles的Diploma2,但我没有获得仅与Diploma2相关的StudentProfiles(没有匹配的Diploma1),这是完美的正常。

所以我有两个问题:

  • 我怎样才能获得所有具有相关Diploma2的StudentProfiles(即使用count(...)> 0添加条件?)
  • 如何将此与带条件的匹配子句(state = 2)?
  • 组合在一起

我希望这很清楚。 感谢

1 个答案:

答案 0 :(得分: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