【问题标题】:CakePHP 3.4: query where or matchingCakePHP 3.4:查询位置或匹配
【发布时间】:2017-09-08 02:47:32
【问题描述】:

我阅读了cookbook,但我不知道如何在一个查询中组合matching()orWhere()

示例:我有属于AlbumPhoto。两者都有active 字段。所以我正在尝试编写一个findInactive() 方法。 “非活动”照片的active 字段为falseactive 字段为false 的相册匹配。

类似这样的:

public function findInactive(Query $query, array $options)
{
    $query->matching('Albums', function ($q) {
            return $q->where(['Albums.active' => false]);
        })
        ->orWhere(['Photos.active' => false])
        ->enableAutoFields(true);

    return $query;
}

但这不起作用:

'SELECT [...] FROM photos Photos INNER JOIN photos_albums Albums ON (Albums.active = :c0 AND Albums.id = (Photos.album_id)) WHERE Photos.active = :c1'

怎么办?谢谢。


编辑

也许一个可能的解决方案是使用contain():

    $query->contain(['Albums => ['fields' => ['active']]])
        ->where(['Photos.active' => false])
        ->orWhere(['Albums.active' => false]);

但是不能用matching()或者innerJoinWith()吗?

【问题讨论】:

  • 如果 Photo belongsTo Album 那么你的最后一个解决方案似乎是最简单的一个。包含创建 JOIN。我认为不需要使用其他解决方案

标签: cakephp cakephp-3.4


【解决方案1】:

将条件添加到主查询

matching()innerJoinWith() 带有条件是错误的方法,因为条件被添加到 INNER 连接 ON 子句,这将导致 Photo 行被排除,以防万一Albums.active 条件不匹配。

如果您只想接收属于相册的照片,那么您想使用matching()innerJoinWith(),但您必须将条件添加到主查询中,即:

$query
   ->innerJoinWith('Albums')
   ->where(['Albums.active' => false])
   ->orWhere(['Photos.active' => false])
   // ...

如果照片不必属于相册,或者是否属于相册并不重要,您可以使用leftJoin()leftJoinWith(),甚至contain()

然而,后者可能会使用 INNER joinStrategy 和/或 select strategy(使用单独的查询),因此您需要注意确保它使用 LEFTjoin 代替。但是,通常仅在您确实想要包含某些东西时才建议使用容器,并且鉴于您的查找器似乎应该只是过滤东西,我会说改用 leftJoinWith()

$query
   ->leftJoinWith('Albums')
   ->where(['Albums.active' => false])
   ->orWhere(['Photos.active' => false])
   // ...

另见

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多