如何将此查询转换为doctrine DQL

时间:2017-03-28 19:36:11

标签: mysql symfony doctrine-orm dql doctrine-query

SELECT apntoken,deviceid,created 
FROM `distribution_mobiletokens` as dm
WHERE userid='20'
and not exists (
    select 1 
    from `distribution_mobiletokens`
    where userid = '20'
    and deviceid = dm.deviceid
    and created > dm.created
    )

此查询的作用是选择用户ID等于20且deviceid相同的所有mobiletokens,但选择该设备的最新apntoken。

我的数据库如下所示。

enter image description here

有关此查询的详细信息,我从此处提出的另一个问题得到了这个答案(How to group by in SQL by largest date (Order By a Group By)

我尝试过的事情

$mobiletokens = $em->createQueryBuilder()
          ->select('u.id,company.id as companyid,user.id as userid,u.apntoken')
          ->from('AppBundle:MobileTokens', 'u')
          ->leftJoin('u.companyId', 'company')
          ->leftJoin('u.userId', 'user')
          ->where('u.status = 1 and user.id = :userid')
          ->setParameter('userid',(int)$jsondata['userid'])
          ->groupby('u.apntoken')
          ->getQuery()
          ->getResult();

       //@JA - Get the list of all the apn tokens we need to send the message to.
       foreach($mobiletokens as $tokenobject){
           $deviceTokens[] = $tokenobject["apntoken"];
           echo $tokenobject["apntoken"]."\n";
       }

        die();

这给了我错误的

响应
63416A61F2FD47CC7B579CAEACB002CB00FACC3786A8991F329BB41B1208C4BA
9B25BBCC3F3D2232934D86A7BC72967A5546B250281FB750FFE645C8EB105AF6
latestone

感谢任何帮助!

其他信息

SELECT * FROM

的数据

enter image description here

使用我提供的SQL后的数据。

enter image description here

2 个答案:

答案 0 :(得分:1)

我现在这样做作为临时修复,但不确定这是否是最佳答案。

$em = $this->em;

       $connection = $em->getConnection();
       $statement = $connection->prepare("
            SELECT apntoken,deviceid,created 
            FROM `distribution_mobiletokens` as dm
            WHERE userid=:userid
            and not exists (
                select 1 
                from `distribution_mobiletokens`
                where userid = :userid
                and deviceid = dm.deviceid
                and created > dm.created
            )");
       $statement->bindValue('userid', $jsondata['userid']);
       $statement->execute();

       $mobiletokens = $statement->fetchAll();

       //@JA - Get the list of all the apn tokens we need to send the message to.
       foreach($mobiletokens as $tokenobject){
           $deviceTokens[] = $tokenobject["apntoken"];
           echo $tokenobject["apntoken"]."\n";
       }

答案 1 :(得分:1)

您可以使用以querybuilder创建的子选择作为示例:

public function selectNewAppToken($userId)
{
    // get an ExpressionBuilder instance, so that you
    $expr = $this->_em->getExpressionBuilder();

    // create a subquery in order to take all address records for a specified user id
    $sub = $this->_em->createQueryBuilder()
        ->select('a')
        ->from('AppBundle:MobileTokens', 'a')
        ->where('a.user = dm.id')
        ->andWhere('a.deviceid = dm.deviceid')
        ->andWhere($expr->gte('a.created','dm.created'));


    $qb = $this->_em->createQueryBuilder()
        ->select('dm')
        ->from('AppBundle:MobileTokens', 'dm')
        ->where($expr->not($expr->exists($sub->getDQL())))
        ->andWhere('dm.user = :user_id')
        ->setParameter('user_id', $userId);

    return $qb->getQuery()->getResult();
}