【问题标题】:Doctrine: Query only where relationship doesn't exist?教义:只查询不存在关系的地方?
【发布时间】:2011-08-11 17:47:15
【问题描述】:

我有两个表:文章和类别。文章可以分配给它们一个类别。但他们不必有一个类别。

架构:

Article:
  columns:
    title:
      type: string(255)
    content:
      type: string(255)
    category_id:
      type: integer(4)

Category:
  columns:
    name:
      type: string(255)
    article_id:
      type: integer(4)
  relations:
    Article:
      class: Article
      local: article_id
      foreign: id
      foreignAlias: ArticleCategories

我可以像这样查询分配了类别的所有文章:

$articles= Doctrine_Query::create()
  ->from('Article a')
  ->leftJoin('a.Category c ON c.article_id = a.id')
  ->where('c.id > 0')
  ->execute();

它返回这个:

Object->Array
(
  [0] => Array
  (
    [id] => string(1) "1"
    [title] => string(4) "test"
    [content] => string(4) "test"
    [Category] => Array
    (
      [0] => Array
      (
        [id] => string(1) "2"
        [name] => string(7) "testing"
      )
    )
  )
etc...

我需要做的是查询没有类别关系的文章。我也不能只说->where('c.id = NULL'),因为如果没有Category 关系,那么对象中就不会返回任何[Category] 数组。它只返回id, title and content。我也不能说->where(a.Category = NULL),因为Category 不是Article 的一列。

有什么想法吗?

更新 我在架构上犯了一个错误并更新了它。我知道类别仅与单个文章有关系并没有真正意义,但实际上我没有使用文章/类别。我只是以这些术语为例。

【问题讨论】:

    标签: php mysql symfony1 doctrine


    【解决方案1】:

    更新

    因此,如果您希望文章作为主要对象,最简单的方法是执行leftJoin,条件为 fk 为空。 LEFT JOINs总是抓取join左边的记录,不管右边是否有对应的记录。因此,如果没有 where 你基本上可以得到所有文章的结果。因此,我们可以使用 where 条件过滤那些没有类别的文章......与之前非常相似:

    $articles = Doctrine_Query::create()
      ->from('Article a')
      ->leftJoin('a.Category c')
      ->where('c.article_id IS NULL')
      ->execute();
    

    没有理由指定on 条件。 Doctrine 会根据实际情况来解决这个问题。此外,对于这种类型的过滤,您不需要使用 where 而是使用内部联接,内部联接只会选择存在关系的项目(即存在 a.category_id = c.id),因此您发布的查询实际上应该是:

    $articles = Doctrine_Query::create()
      ->from('Article a')
      ->innerJoin('a.Category c')
      ->execute();
    

    要获取没有任何类别的文章,您可以在 article 上查找为 null 的 category_id

    $articles= Doctrine_Query::create()
      ->from('Article a')
      ->leftJoin('a.Category c')
      ->where('a.category_id IS NULL')
      ->execute();
    

    我可能会删除连接,因为它并不是真正必要的,除非您出于某种原因需要结果中的空列。

    【讨论】:

    • 哦...是的,我想就是这么简单。谢谢。如果 relations: 是在 Category 表而不是 Article 表中定义的,我该怎么办?
    • 啊,谢谢。我很接近,但我在做= NULL 而不是IS NULL。 MySQL的错误而不是Doctrine。但也感谢有关连接的提示!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-08
    • 2012-05-24
    相关资源
    最近更新 更多