【问题标题】:Left Join with Where clause returns empty resultLeft Join with Where 子句返回空结果
【发布时间】:2012-07-17 16:27:45
【问题描述】:

我有一个post 表,它的架构是这样的:

CREATE TABLE IF NOT EXISTS `post` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` bigint(20) DEFAULT NULL,
  `site_id` bigint(20) DEFAULT NULL,
  `parent_id` bigint(20) DEFAULT NULL,
  `title` longtext COLLATE utf8_turkish_ci NOT NULL,
  `status` varchar(20) COLLATE utf8_turkish_ci NOT NULL,
  PRIMARY KEY (`id`),
  KEY `IDX_5A8A6C8DA76ED395` (`user_id`),
  KEY `IDX_5A8A6C8DF6BD1646` (`site_id`),
  KEY `IDX_5A8A6C8D727ACA70` (`parent_id`),
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_turkish_ci AUTO_INCREMENT=16620 ;

我正在使用此 DQL 来获取帖子及其子项:

$post = $this->_diContainer->wordy_app_doctrine->fetch(
           "SELECT p,c FROM Wordy\Entity\Post p LEFT JOIN p.children c WHERE p.site = :site AND p.id = :id AND p.language = :language AND p.status != 'trashed'  AND c.status != 'trashed' ORDER BY c.title",
           array(
               'params' => array(
               'id' => $id,
               'site' => $this->_currentSite['id'],
               'language' => $this->_currentLanguage->code,
           )
       )
   );

我想要做的是:获取一个帖子和它所有的孩子。标准是,不包括已删除的帖子或已删除的儿童。

但是当我用一个甚至没有孩子的帖子运行这个查询时,返回的结果集是空的。

当我从查询中删除 c.status != 'trashed' 部分时,一切正常,但我也会收到垃圾帖子。

谢谢,提前。

编辑:这是给定 DQL 的 SQL 输出:

SELECT p0_.id AS id0, p0_.title AS title5, p0_.status AS status8, p0_.parent_id AS parent_id9, p1_.id AS id15, p1_.title AS title20, p1_.status AS status23, p1_.parent_id AS parent_id24 FROM post p0_ LEFT JOIN post p1_ ON p0_.id = p1_.parent_id WHERE p0_.site_id = ? AND p0_.id = ? AND p0_.language = ? AND p0_.status <> 'trashed' ORDER BY p1_.title ASC

【问题讨论】:

    标签: mysql sql doctrine-orm dql


    【解决方案1】:

    您忘记了left join syntaxON 子句。

    【讨论】:

      【解决方案2】:

      您的长条件 WHERE 在加入后被“与”在一起,没有任何东西通过所有检查。将连接内容移到 ON 子句中,并将 c.trashed 检查留在 WHERE 子句中。试试这样的:

      SELECT p,c FROM Wordy\Entity\Post p LEFT JOIN children c ON p.site = :site AND p.id = :id AND p.language = :language AND p.status != 'trashed' AND p.id = c.parent_id  WHERE   c.status != 'trashed' ORDER BY c.title
      

      【讨论】:

      • 感谢您的回答,但不是 SQL,是 DQL,Doctrine 不支持 ON 子句:docs.doctrine-project.org/projects/doctrine-orm/en/latest/…
      • @cnkt 啊,DQL...您不需要将 DQL 与学说一起使用,您可以指定原始查询。在这种情况下,对于您正在尝试的事情,这可能是最简单的事情。可能有一种 DQL 方法可以做到这一点,但我避免像瘟疫一样使用 DQL :)
      • 谢谢,我会寻找一种使用 DQL 的方法。 :)
      【解决方案3】:

      我想我解决了我自己的问题。

      只需在join 字段上使用with 子句而不是where 子句,如下所示:

      "SELECT p,c FROM Wordy\Entity\Post p LEFT JOIN p.children c WITH c.status != 'trashed' WHERE p.site = :site........."
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-03-25
        • 1970-01-01
        • 2021-02-15
        • 2017-07-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多