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

Cakephp 多个匹配()和contain(),相关记录计数的条件,cakephp,cakephp-3.0,Cakephp,Cakephp 3.0,使用CakePHP3.x,我有3个模型:StudentProfile、文凭1和文凭2 学生简介有许多文凭1 学生简介有许多文凭 1有一个整数“状态”字段 我需要获取学生档案,其中: 有一个(或多个)相关文凭1,其中文凭1.state=2 或 有一个(或多个)文凭2(文凭2字段无条件) 我需要用我的学生档案检索匹配的文凭1和文凭2 我正在使用搜索和分页器组件,所以我必须用一个查询来完成这项工作 现在,我已经能够通过以下方式获得第一部分: $query = $this->Student

使用CakePHP3.x,我有3个模型:StudentProfile、文凭1和文凭2

  • 学生简介有许多文凭1
  • 学生简介有许多文凭
1有一个整数“状态”字段

我需要获取学生档案,其中:

  • 有一个(或多个)相关文凭1,其中文凭1.state=2 或
  • 有一个(或多个)文凭2(文凭2字段无条件)
我需要用我的学生档案检索匹配的文凭1和文凭2

我正在使用搜索和分页器组件,所以我必须用一个查询来完成这项工作

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

$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));
结合匹配和包含允许我添加条件并获得相关的条件1(据我所知)

现在我还需要获得所有相关文凭的学生资料2,这就是我被卡住的地方。如果我加上

->contain(['Diploma2'])
…对于我的查询,我只获取具有匹配的文凭1(其中state=2)的StudentProfiles的文凭2,但我没有获取仅具有相关的文凭2(没有匹配的文凭1)的StudentProfiles,这是完全正常的

所以我有两个问题:

  • 如何获取所有具有相关文凭2(即使用count(…)>0添加条件)的学生档案
  • 如何将其与带有条件(state=2)的匹配子句组合
我希望这是清楚的。
谢谢,这是一种稍微不同的方法,但也许会有帮助

$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

,但可能会有所帮助

$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

在我的第一次测试中效果非常好:),非常感谢这节“用蛋糕查询”课!我只是不明白为什么我们需要leftJoinWith和contain,但它是有效的。@Flo
contain
就像是一个不同的作用域,所以
主查询
甚至不知道
contain
上的数据,这就是为什么你需要使用
join
而不是
contain
。在我的第一次测试中效果很好:),非常感谢这节“蛋糕查询”课!我只是不明白为什么我们需要leftJoinWith和contain,但它是有效的。@Flo
contain
它就像一个不同的作用域,所以
主查询
甚至不知道
contain
上的数据,这就是为什么你需要使用
join
而不是
contain