其中 IN 查询 关于教义 多对多标签关系



一点背景:

  • 我有办公室实体。
  • 办公室可能有文章。
  • 文章有标签。
  • 主管局
  • 可以与其他主管局共享标签(因此也可以共享文章)。

现在,我正在尝试构建一个查询,该查询显示:"获取属于我的办公室或具有已与我的办公室共享的标签的所有文章"。

我已经在 MySQL 中尝试过这个,以下查询按预期工作:

SELECT 
    *  
FROM 
    `articles` `a` 
WHERE 
    (
        `office_id` = 2 
        OR 
        `a`.`id` IN (
            SELECT 
                `at`.`article_id` 
            FROM 
                `article_tags` `at` 
            WHERE 
                `at`.`article_id` = `a`.`id` 
            AND 
                `at`.`tag_id` IN 
                (
                    SELECT 
                        `st`.`tag_id` 
                    FROM 
                        `shared_tags` `st` 
                    WHERE 
                        `st`.`shared_with_id` = 2 
                    AND 
                        `st`.`article` = 1
                )
            )
    ) 
AND 
    `status` = 1

我的实体如下:

/**
 * @ORMManyToMany(targetEntity="Tag", inversedBy="articles")
 * @ORMJoinTable(name="article_tags")
 * @var ArrayCollection|Tag[]
 */
protected $tags;

标记

/**
 * @ORMManyToMany(targetEntity="Article", mappedBy="tags")
 * @var ArrayCollection|Article[]
 */
protected $articles;

共享标签

class SharedTag extends Entity
{
    /**
     * @ORMId
     * @ORMGeneratedValue
     * @ORMColumn(type="integer")
     * @var int
     */
    protected $id;
    /**
     * @ORMManyToOne(targetEntity="Office", inversedBy="sharedTags")
     * @ORMJoinColumn(name="shared_with_id", referencedColumnName="id")
     * @var Office
     */
    protected $sharedWith;
    /**
     * @ORMManyToOne(targetEntity="Office", inversedBy="sharedTags")
     * @ORMJoinColumn(name="shared_by_id", referencedColumnName="id")
     * @var Office
     */
    protected $sharedBy;
    /**
     * @ORMManyToOne(targetEntity="Tag", inversedBy="sharedTags")
     * @var Tag
     */
    protected $tag;
    /**
     * @ORMColumn(type="boolean", options={"default" = 0})
     * @var bool
     */
    protected $template = 0;
    /**
     * @ORMColumn(type="boolean", options={"default" = 0})
     * @var bool
     */
    protected $article = 0;
    /**
     * @ORMEmbedded(class = "ValueObjectsCreatedAt", columnPrefix=false)
     * @var CreatedAt
     */
    protected $createdAt;
}

那么,如何在 DQL 或 QueryBuilder 中查询它呢?我已经尝试了几种方法,但我似乎无法在 WHERE IN() 查询中使用关系articles.tags中的tag_id

提前谢谢你!


编辑:

经过一些试验和错误,多亏了 Jean 的回答,我能够像这样查询它:

SELECT
  a
FROM
  Article a
LEFT JOIN a.tags t
LEFT JOIN a.office o
LEFT JOIN o.sharedTags st
WHERE
  (
    a.office = :office
    OR
    (
      t = st.tag
      AND
      st.sharedWith = :office
      AND
      st.article = 1
    )
  )
AND
  a.status.status = :status
AND
  a.template IS NULL
GROUP BY a.id

您应该使用连接而不是子查询。这样,您可以获得更好的性能和更简单的 DQL 代码:

SELECT DISTINCT `a`
FROM `articles` `a` 
LEFT JOIN `a.tags` `t`
LEFT JOIN `t.shared_with_id` `o`
WHERE (`a`.`office_id` = 2 OR `o`.`id` = 2) 
AND `status` = 1

相关内容

  • 没有找到相关文章

最新更新