Mysql 如何在条令中进行复杂的SQL查询

Mysql 如何在条令中进行复杂的SQL查询,mysql,symfony,doctrine-orm,doctrine-query,Mysql,Symfony,Doctrine Orm,Doctrine Query,我有两个表:用户和他们的积分 用户具有以下字段: 身份证 名字 点具有以下字段: 身份证 开始日期 结束日期 点数 用户id 因此,一些用户可能有点或没有点。积分条目受从开始日期到结束日期的时间间隔限制,并具有用户在此时间间隔内拥有的点数 我需要显示用户表,按此时点的总和排序时间戳必须介于开始日期和结束日期之间,并在以后的视图中显示此总和值。如果用户没有点数,则此计数必须等于0 我有这样的想法: $qb = $this->getEntityManager() ->ge

我有两个表:用户和他们的积分

用户具有以下字段:

身份证

名字

点具有以下字段:

身份证

开始日期

结束日期

点数

用户id

因此,一些用户可能有点或没有点。积分条目受从开始日期到结束日期的时间间隔限制,并具有用户在此时间间隔内拥有的点数

我需要显示用户表,按此时点的总和排序时间戳必须介于开始日期和结束日期之间,并在以后的视图中显示此总和值。如果用户没有点数,则此计数必须等于0

我有这样的想法:

$qb = $this->getEntityManager()
        ->getRepository('MyBundle:User')
        ->createQueryBuilder('u');
    $qb->select('u, SUM(p.count_of_points) AS HIDDEN sum_points')
        ->leftJoin('u.points', 'p')
        ->orderBy('sum_points', 'DESC'); 
$qb->groupBy('u');
        return $qb->getQuery()
            ->getResult();
SELECT u.id, u.name, COALESCE(SUM(p.count_of_points),0) AS sum_points 
FROM Users u 
LEFT JOIN Points p ON p.user_id=u.id 
WHERE (p.start_date <= 1463578691 AND p.end_date >= 1463578691) OR p.id IS NULL
GROUP BY u.id
ORDER BY sum_points DESC
但这并没有日期间隔的限制,也并没有我可以从对象的视图中使用的求和点字段

我试图找到如何解决此任务,我在SQL中做了如下操作:

SELECT u.*, up.points FROM users AS u LEFT OUTER JOIN
      (SELECT u.*, SUM(p.count_of_points) AS points FROM `users` AS u
      LEFT OUTER JOIN points AS p ON p.user_id = u.id
      WHERE p.start_date <= 1463578691 AND p.end_date >= 1463578691
      ) AS up ON u.id = up.id ORDER BY up.points DESC
但这个查询只给我在points表中有条目的用户,所以我想我必须使用另一个连接来添加没有点数的用户。这是一个复杂的问题。我不知道如何在原则中实现这一点,因为DQL不能使用带有左连接的内部查询

也许还有其他方法可以解决这个问题?也许我的表格模式是错误的,我可以用不同的方法来做吗?

编辑:忘记日期条件。更正答案:

在纯MySQL中,您的查询如下所示:

$qb = $this->getEntityManager()
        ->getRepository('MyBundle:User')
        ->createQueryBuilder('u');
    $qb->select('u, SUM(p.count_of_points) AS HIDDEN sum_points')
        ->leftJoin('u.points', 'p')
        ->orderBy('sum_points', 'DESC'); 
$qb->groupBy('u');
        return $qb->getQuery()
            ->getResult();
SELECT u.id, u.name, COALESCE(SUM(p.count_of_points),0) AS sum_points 
FROM Users u 
LEFT JOIN Points p ON p.user_id=u.id 
WHERE (p.start_date <= 1463578691 AND p.end_date >= 1463578691) OR p.id IS NULL
GROUP BY u.id
ORDER BY sum_points DESC
COALESCE函数发回第一个NOTNULL参数,因此如果用户没有点,那么和将导致NULL,但COALESCE为0

我不确定是否使用条令查询生成器进行翻译,但您可以尝试:

$qb = $this->getEntityManager()->createQueryBuilder();

$qb->select('u')
   ->addSelect('COALESCE(SUM(p.count_of_points),0) AS sum_points')
   ->from('User', 'u')
   ->leftjoin('u.points', 'p')
   ->where('(p.start_date <= ?1 AND p.end_date >= ?1) OR p.id IS NULL')
   ->groupBy('u.id')
   ->orderBy('sum_points','DESC')
   ->setParameter(1, $date_now);

不幸的是,您的变体只为用户提供点条目。普通SQL还是DQL查询?因为我测试了纯SQL,它会给所有用户,包括那些没有分数的用户。好吧,我看到问题了,我忘记了测试中的日期条件。。。当用户没有点数时,LEFT JOIN子句返回一行结果,其中u.id和u.name已填充,p.id=NULL,p.start\u date=NULL,p.end\u date=NULL。。。因此,为了不从请求中排除这些行,在WHERE子句中添加a或p.id为NULL。