【问题标题】:Doctrine subquery on FROM statement, Symfony 3FROM 语句上的教义子查询,Symfony 3
【发布时间】:2017-07-08 17:23:01
【问题描述】:

Doctrine 新手并尝试将下面的 MySQL 查询转换为 queryBuilder。

SELECT COUNT(t2.user_id) FROM(
    SELECT t2.* FROM logins t2
        WHERE t2.login_time >= DATE_SUB(NOW(),INTERVAL 5 HOUR)
        LIMIT 10
    ) t2
WHERE t2.is_success = 1

我在 SO 上的 WHERE 子句中看到了一些子查询示例,并尝试按照以下方式对其进行调整,但这并没有真正奏效。

        $sub = $this->createQueryBuilder('l')
        ->select('l')
        ->where('l.loginTime >= :date
            and l.userId = :user_id')
        ->setParameters( $parameters )
        ->getDQL();

    $qb = $this->createQueryBuilder('a')
        ->select('count(a.id)')
        ->from( $sub, 'a' )
        ->where('a.isSuccess = 0'); 
    return $qb->getQuery()->getSingleScalarResult(); 

谢谢

【问题讨论】:

标签: php mysql symfony doctrine-orm


【解决方案1】:

使用这个查询,

$date = new Doctrine_Expression('DATE_SUB(NOW() , INTERVAL 5 HOUR)');
$query
->select('count(t2.userId)')
->from('Login', 't2')
->where('t2.loginTime >= :date')
->andWhere('t2.isSuccess = 1')
->setParameter('date',$date);
->setMaxResults(10);    

【讨论】:

  • 我改了脚本
  • 谢谢。我在 from 子句上收到错误 -> 未定义类登录
  • :) 很好,然后很好。
  • ok 解决了未定义的问题,但查询不会产生与 mySQL 查询相同的结果。它应该产生一个 0-10 之间的数字,因为这是子查询的限制,但不是。
【解决方案2】:

正如@colburton 指出的那样,Doctine 似乎无法处理这样的子查询。 Check this post.

所以,我发布了我找到的可能的解决方案,希望有人能纠正我或改进它。

备选方案 1 - 虽然我没有验证它,但似乎 Native SQL 能够处理它。缺点是它看起来相当复杂,尤其是当有更明智的选择时。

备选方案 2 - 运行普通的旧 mySQL 查询。鉴于结果是一个很好的标量。我就是这样设置的。

UsedBundle/Repository/LoginRepository.php

public function countAllFailedMysqlAction()
{
    $ulink = new \PDO("mysql:host=$hostname;dbname=$database;charset=utf8", $username, $password);
    $sql = "SELECT COUNT(t2.user_id) FROM(
        SELECT t2.* FROM logins t2
        WHERE t2.login_time >= DATE_SUB(NOW(),INTERVAL 5 HOUR)
        LIMIT 10
        ) t2
        WHERE t2.is_success = 0";
        $stmt = $ulink->query($sql); 
        return $stmt->fetchColumn();
}

备选方案 3 - 在这个特定实例中,可以使用常规实体运行内部或子查询,返回一个数组并遍历它以获得结果。

UsedBundle/Repository/LoginRepository.php

public function countAllFailedAction()
{
    $date = new \DateTime();
    $date->modify('-24 hour');

    $qb = $this->createQueryBuilder('l')
        ->select('l.id,l.isSuccess')
        ->where('l.loginTime >= :date')
        ->setParameter('date', $date)
        ->setMaxResults(10);
    $logins = $qb->getQuery()->getArrayResult();

    $ct_failed = 0;
    foreach( $logins as $login ){
        if($login['isSuccess'] == false ){ $ct_failed++;}
    }
    return $ct_failed;        
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    • 2017-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-28
    • 1970-01-01
    相关资源
    最近更新 更多