2017-10-13 111 views
1

我有一个问题表及答案(结果)表该symfony的应用程序不同:主义的左连接的行为与相关联的每个问题,普通的SQL

问题表:

id | question_title 
------------------- 
1 | Name? 
2 | Age? 

结果表:

id | answer_text | question_id | user_id 
---------------------------------------- 
1 | John  | 1   | 10 
2 | Peter  | 1   | 11 
3 | 24   | 2   | 10 

用户可能跳过问题,因此它可能不是答案表中给定问题的匹配答案。但是,当我检索给定用户的结果时,我想要全面列出每个问题和相关答案,或者为空,以防万一它不存在。因此,(在普通的SQL)我离开加入这样的:

SELECT question_text, answer_text FROM `question` left join result on question.id = result.question_id and user_id=10 

获取我:

question_text | answer_text 
---------------------------------------- 
Name?   | John 
Age?   | 24 

对于USER_ID 11,这看起来像:

question_text | answer_text 
---------------------------------------- 
Name?   | Peter 
Age?   | null 

正是我所期望的。

当我尝试将此查询转换为dql查询时出现问题。我这样做是这样的:

$qb->select('q.question_title, r.answer_text'); 
    $qb->from('AppBundle:Question', 'q'); 
    $qb->leftJoin(
     'AppBundle:Result', 
     'r', 
     \Doctrine\ORM\Query\Expr\Join::WITH, 
     'q.id = r.question' 
    ); 
    $qb->where('r.user = '.$user->getId()); 

    $answer= $qb->getQuery()->getResult(); 

对于在连接的右侧具有匹配数据的数据集,它工作正常。但是,当右侧为空时,它会从返回的数组中除去,但getResult。这将高于纯SQL的第一个例子转储:

array:2 [ 
    0 => array:2 [ 
     "question_title" => Name? 
     "answer_text" => "John" 
    ] 
    1 => array:2 [ 
     "question_title" => Age? 
     "answer_text" => "24" 
    ] 
] 

这是第二个例子转储。没有匹配的答案,我得到的只是1个元素的数组:

array:2 [ 
    0 => array:2 [ 
     "question_title" => Name? 
     "answer_text" => "Peter" 
    ] 
] 

我不知道是否有任何的方式来模仿实际的行为我与左连接在普通的SQL。

顺便说一下,数据库引擎即时通讯使用的是MySQL,以防万一。

编辑:实际上不是什么在Doctrine2 LEFT JOIN with 2 conditions被问。以为我有相同的查询在DQL和SQL中表现不同。原来,我只是把它翻译过来。

+1

的可能的复制[Doctrine2 LEFT加入2个条件](https://stackoverflow.com/questions/15815869/doctrine2-left-join-with-2-conditions)这显然是基本的,你发现了什么谷歌搜索,说'教条左连接多个' ? – philipxy

+0

那真的不是我所问的。我以为我在SQL中的查询在DQL中的表现有所不同,但我实际上是在翻译它错误,正如下面的用户所指出的那样。 –

+0

在这个问题中,*问*是什么(尽管它的(不好))标题)是为什么结果以某种方式出现错误,给出了一些'join's&a'where'。因此,对问题的合理描述包括您的情况。在这个问题中*回答的是,提问者在他们需要“开”时错误地将条件放在“哪里”。这是你的问题的答案。这也是其他许多点击,也从变体点击。我*发现*由我给的谷歌回答。所以... – philipxy

回答

1

如果你看到DQL查询你想在加入结果集应用WHERE条款,所以你的过滤器正常工作,并筛选出结果,其中用户ID不是11

现在,如果你看看你的SQL查询你没有使用WHERE子句试图加入结果表与问题ID和用户是11,所以它会加入结果表中的行,其中用户ID是11,并为非匹配行生成空。

有(后进行连接操作),其具有上ON子句和WHERE,上ON子句过滤器将同时WHERE被施加到连接结果集中在接合时只工作的过滤器的差。

要编写DQL相当于你的SQL可以写成

SELECT q.question_title, r.answer_text 
FROM AppBundle:Question q 
LEFT JOIN AppBundle:Result r 
    WITH q.id = r.question AND r.user = :user 

其更好地在你的实体定义的映射,而不是执行手动加入Association Mapping

+0

是的,这是显而易见的,出于某种原因,我一直在想我的原始SQL中有一个位置过滤器。底线:我的错。谢谢。 –