【问题标题】:How to query HasMany Association based on single value in CakePHP 3.x如何在 CakePHP 3.x 中基于单个值查询 HasMany 关联
【发布时间】:2019-04-09 13:12:20
【问题描述】:

我有一个文章表和一个评论表。 文章有很多评论。 每个评论都属于一个评论状态(comment_status_id): 1. 好,或 2. 不好,或 3.丑。

我想查询所有只有状态为 3(丑陋)的评论的文章。也就是说,排除具有状态 1 或 2 的评论的文章。

我可以编写一个子查询和查询来获取所有带有 Status Ugly 评论的文章:

$matchingComments = $this->Articles->getAssociation('Comments')->find()
    ->select(['article_id'])
    ->distinct()
    ->where(['comment_status_id' => 3]);

$query = $this->Articles->find()
    ->where(['Articles.id IN' => $matchingComments]);

这为我提供了所有评论状态为 3 的文章。但它也包括评论状态为 2 或 1 的文章以及至少一个状态为 3 的评论。

所以我的问题是: 是否有一种高效/优雅的方法可以使此查询与查询生成器一起使用,因此结果只有评论为 ALL comment_status 3(丑陋)的文章?

我确定我可以使用 for 循环解析 $query 结果并构建一个新的结果数组,但我想看看在初始查询中是否有更好的方法和/或/with子查询。 提前感谢您的任何建议!

D.

【问题讨论】:

  • 你知道如何在原始 SQL 中做到这一点吗?最好先弄清楚这一点。
  • 感谢 ndm.... 是的,这是解决问题的正确方法。我将在下面添加我的解决方案。

标签: cakephp associations cakephp-3.x querying


【解决方案1】:

按照 ndm 的建议让原始 sql 首先工作,此查询适用于我的 matchingComments 查询

SELECT `article_id`
FROM `comments`
GROUP BY `article_id`
HAVING MIN(`comment_status_id`) = 3
AND MAX(`comment_status_id`) = 3;

那么在我的 Cake 控制器中,这可以工作:

$matchingComments = $this->Articles->getAssociation('Comments')->find()
    ->select(['article_id'])
    ->group('article_id')
    ->having(['MIN(comment_status_id)' => 3])
    ->having(['MAX(comment_status_id)' => 3])

$query = $this->Articles->find()
    ->where(['Articles.id IN' => $matchingComments]);

不确定是否有更好的方法,但效果很好。 再次感谢ndm。 D.

【讨论】:

    【解决方案2】:

    来自Cake Book - Retrieving Data & Results Sets

    $articles = $this->Articles
        ->find()
        ->contain(['Comments'])
        ->notMatching('Comments.CommentStatus', function($q) {
            return $q->where(['CommentStatus.comment_status_id' => '3'];
        });
    

    【讨论】:

    • 谢谢丹尼斯。这种方法会生成一个包含不是状态 3 的 cmets 的所有 Articles 的列表,并按评论列出它们,因此在列表中多次重复相同的 article_id,因此不是目标。无论如何,我会尝试使用 match 和 notMatching 的组合,看看效果如何。谢谢。
    • 试着把“notMatching”放到静态函数里面包含像 'Comments' => static function ($q) = {return $q->notMatching.....};
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-05
    • 2016-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多