mysql - 如何查询相关实体但返回根实体?

标签 mysql symfony doctrine dql

这是一个假设性的问题,因为我正试图了解 Doctrine ORM 并且很难复制我在普通 SQL 中所做的事情。

假设我在标签和帖子之间有一个简单的 ManytoMany 关系。它们会映射,以便 Post::tags 是拥有方,Tag::posts 是反向映射。

我知道使用 Doctrine 的 DQL 我可以选择包含他们的标签的帖子,或者使用以下 2 个查询引用他们的帖子的标签

(1) SELECT p, t FROM MyBundle:Post p JOIN p.tags t WHERE p.id = :id

(2) SELECT t, p FROM MyBundle:Tag t JOIN t.posts p WHERE t.id = :id

但是当我想通过多个标签获取帖子时,我必须在这些标签之间进行选择:

(3) SELECT p, t FROM MyBundle:Post p JOIN p.tags t WHERE t.value IN ('foo','bar')

(4) SELECT t, p FROM MyBundle:Tag t JOIN t.posts p WHERE t.value IN ('foo','bar')

这两个似乎都是错误的。

对于 (3),我想数据库会扫描整个 posts 表,然后再将集合缩减为那些已标记的

通过 (4),我得到了标签对象的集合,这与我所追求的相反。

我尝试了以下方法,因为从逻辑上讲它似乎反射(reflect)了我在 SQL 中所做的事情:

SELECT p, pt FROM MyBundle:Tag t JOIN t.posts p JOIN p.tags pt
                 WHERE t.value IN ('foo','bar') GROUP BY p.id

它不起作用,因为 Doctrine 坚持要我选择根实体

选择标签但返回唯一帖子作为完整对象的最佳方法是什么?

最佳答案

如果我很好地理解了这个问题,您想要的是选择所有至少有一个标签的帖子,标签的值在定义的集合(“foo”、“bar”、...)中,并忽略所有其他帖子。

让我们从 (3) 开始:

SELECT p, t FROM MyBundle:Post p JOIN p.tags t WHERE t.value IN ('foo','bar')

在 MySQL 中,这大约意味着:“选择所有具有值为 foo 或 bar 的标签的帖子”。

但是在 DQL 中,这意味着“选择所有帖子并仅附加值为 foo 或 bar 的标签”。这意味着查询将返回所有帖子的集合,但会过滤标签。这种行为差异是由于 doctrine 必须使用数据库层返回的数组创建对象。当您使用 JOIN 进行 MySQL 查询时,结果将是一个包含重复项的数组。但是,在对象世界中,必须将重复的帖子合并到一个 Post 对象中......

我相信您的查询的解决方案是在进行连接时进行过滤:

SELECT p,t FROM MyBundle:Post p JOIN p.tags t WITH t.value IN ('foo', 'bar')

WITH DQL子句可以理解为在ON MySQL子句中加了一个条件。 IE。上面的查询类似于下面的 MySQL 查询:

SELECT p.*, t.* FROM posts AS p JOIN posts_tags AS pt ON pt.post_id = p.id JOIN tags AS t ON pt.tag_id = t.id AND t.value IN ("foo", "bar")

请注意,不再有 WHERE 子句。在 JOIN 条件子句中移动的条件...

希望这会有所帮助 ;-)

关于mysql - 如何查询相关实体但返回根实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13612496/

相关文章:

php - 1 个查询中有 2 个数据库

MySQL:获取行集中每个排序列的差异

php - Symfony2 : Why is the Request passed to a Kernel. 在 Symfony2 中终止受 AppCache 影响的 EventListener

mysql - silex 将一个 SQL 语句循环到另一个 SQL 语句上

symfony - 在nelmio-alice中引用固定项目

mysql - 选择最后一个事件类型为 X 的所有用户

mysql - Doctrine Query Builder CONCAT in GROUP BY

mysql - SQL Genius需要..复杂的MySQL查询

php - 使用 yaml 路由描述时如何在运行时获取 Symfony2 中的路由名称?

php - fatal error 异常 : Error: Call to a member function has() on a non-object