我正在尝试将此SQL转换为DQL或查询构建器变体的外观.
select *
from project_release r
where (select s.title as status_name
from release_status_log l
left join release_status s
on l.release_status_id = s.id
where l.release_id = r.id
order by l.created_at desc
limit 1
) not in ('Complete', 'Closed')
;
从Release实体的存储库类内部,我试过这个
return $this->getEntityManager()->createQuery("
select r.*
from MyBundle:Release r
where (select s.title
from MyBundle:ReleaseStatusLog l
join l.status s
where l.release = r
order by l.createdAt desc
limit 1
) IN ('Complete','Closed')
order by r.release_date ASC
limit 10
")->getArrayResult();
这给出了错误
[Syntax Error] line 0, col 265: Error: Expected
Doctrine\ORM\Query\Lexer::T_CLOSE_PARENTHESIS, got ‘limit’
这是指子查询中的限制1.
那么我试过这个
return $this
->createQueryBuilder('r')
->select('r.*')
->where("(select s.title
from MyBundle:ReleaseStatusLog l
join l.status s
where l.release = r
order by l.created_at desc
limit 1
) $inClause ('Complete', 'Closed')
")
->setMaxResults( $limit )
->orderBy('release_date', 'ASC')
->getQuery()
->getArrayResult()
;
这给出了同样的错误.如何在父查询中执行每行限制为1行的子查询?
> Symfony 2.0.15
>学说2.1.7
> PHP 5.3.3
> MySQL 5.1.52
最佳答案 我现在有一个解决方案.我最终回退到本机查询系统,结果集映射来自问题中的实体.
它不是一个很好的解决方案,但它可以工作,直到我看到另一个解决方案,它是这种类型的WHERE子句的唯一选择.
这就是我的finder方法现在的样子
/**
* Finds Releases by their current status
*
* @param array $statuses White-list of status names
* @param boolean $blackList Treat $statuses as a black-list
* @param integer $limit Limit the number of results returned
* @param string $order Sort order, ASC or DESC
*
* @throws \InvalidArgumentException
*
* @return array <Release>
*/
public function findByCurrentStatus( array $statuses, $blackList=false, $limit=null, $order='ASC' )
{
if ( empty( $statuses ) )
{
throw new \InvalidArgumentException( "Must provide at least one status" );
}
$inClause = $blackList ? 'not in' : 'in';
$rsm = new ResultSetMappingBuilder($this->getEntityManager());
$rsm->addRootEntityFromClassMetadata('MyBundle:Release', 'r');
$SQL = "
select *
from project_release r
where (select s.title as status_name
from release_status_log l
left join release_status s
on l.release_status_id = s.id
where l.release_id = r.id
order by l.created_at desc
limit 1
) $inClause ('" . implode( "','", $statuses ) . "')
order by r.release_date $order
";
if ( $limit )
{
$SQL .= " limit $limit";
}
return $this
->getEntityManager()
->createNativeQuery( $SQL, $rsm )
->getResult()
;
}
我有点厌恶回到构建一个字符串的查询,但哦,好吧.哦,对于你的鹰眼,$status不是来自用户数据,所以这里没有SQL注入漏洞;)