1

我有一个属于的Price关联Season

我正在尝试查询在季节中通过时与特定日期范围匹配的所有价格以及任何没有的价格(Prices.season_id=0

这是我所拥有的:

// build the query
$query = $this->Prices->find()
  ->where(['product_id'=>$q['product_id']])
  ->contain(['Seasons']);

if(!empty($to_date) && !empty($from_date)) {
  $query->matching('Seasons', function ($q) {
    return $q->where([
      'from_date <= ' => $to_date,
      'to_date >= ' => $from_date
    ]);
  });
}

但是,这只会返回与季节明确关联的价格。我如何让它也返回 Price.season_id=0 ?

4

1 回答 1

0

$query->matching()调用在内部创建 aINNER JOIN并将回调函数的 where 语句放入ONjoin 子句中。要检索没有关联的项目,您需要一个LEFT JOIN. 所以你的代码片段看起来像这样:

if(!empty($to_date) && !empty($from_date)) {
    $query->leftJoinWith('Seasons', function ($q){return $q;});
    $query->where([[
        'or' => [
            'Season.id IS NULL',
            [
                'from_date <= ' => $to_date,
                'to_date >= ' => $from_date,
            ],
        ],
    ]]);
}

因此,我们创建一个普通INNER JOIN并将条件放在where查询的普通(最外)子句中。

双数组用于消除可能具有or连接的其他 where 条件的歧义。

我自己偶然发现了column IS NULL而不是'column' => null语法。

PS:这适用于所有协会。对于hasMany并且belongsToMany您必须将结果与$query->group('Prices.id')

于 2016-10-28T23:14:39.227 回答