3

这是我的 Symfony2 项目的 2 个表:

+-----------+     +----------------------------+ 
|  EVENT    |     |         PHOTO              |
+-----------+     +------+-----------+---------+
|    id     |     | id   | event_id  |  likes  |
+-----------+     +------+-----------+---------+
|     1     |     |  1   |    1      |   90    |
|     2     |     |  2   |    1      |   50    |
+-----------+     |  3   |    2      |   20    |
                  |  4   |    2      |   10    |
                  +------+-----------+---------+

我想选择最喜欢的照片的 2 个事件,看起来像:

+------------+------------+---------+  
|  event_id  |  photo_id  |  likes  |  
+------------+------------+---------+
|     1      |     1      |    90   |
+------------+----------------------+
|     2      |     3      |    20   |
+------------+----------------------+

此处解释了 SQL 解决方案(SQL Select only rows with Max Value on a Column)并且可能是:

SELECT p.event_id, p.likes, p.id
FROM photo p
INNER JOIN(
    SELECT event_id, max(likes) likes
    FROM photo
    GROUP BY event_id
) ss on p.event_id = ss.event_id and p.likes = ss.likes

什么是 DQL 查询?我尝试了很多东西,但总是出错。

4

4 回答 4

2

我没有设法使用 DQL 找到合适的答案,但是通过学说,有一种方法可以使用他们所谓的 Native Query 来处理 SQL 查询。

我设法使用 Native Query 模块和 Symfony 2 创建了您的 SQL 示例的工作示例

use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query\ResultSetMapping;

class PhotoRepository extends EntityRepository
{
    public function findSomeByEvent()
    {
        $rsm = new ResultSetMapping;
        $rsm->addEntityResult('theNameOfYourBundle:Photo', 'p');
        $rsm->addFieldResult('p', 'id', 'id');
        $rsm->addFieldResult('p', 'likes', 'likes');
        $rsm->addFieldResult('p', 'event', 'event');

        $sql = 'SELECT p.event_id, p.likes, p.id
                FROM Photo p
                INNER JOIN(
                    SELECT event_id, max(likes) likes
                    FROM Photo
                    GROUP BY event_id
                ) ss on p.event_id = ss.event_id and p.likes = ss.likes';
        $query = $this->_em->createNativeQuery($sql, $rsm);

        $resultats = $query->getArrayResult();

        return $resultats;
    }
}

这是文档的链接:Native Query,如果答案没有按预期工作

于 2013-04-24T14:34:35.793 回答
1

要使用 DQL 执行此操作,您可以使用以下方法,使用子查询方法处理相同的方法很难用教义做,所以我使用方法而不使用聚合函数

SQL 演示

$DM      = $this->get( 'Doctrine' )->getManager();
$DQL     = 'SELECT a 
        FROM AppBundle\Entity\Photo a
        LEFT JOIN AppBundle\Entity\Photo b WITH a.event = b.event AND a.likes < b.likes
        WHERE b.id IS NULL
        ORDER BY a.likes DESC
        ';
$query   = $DM->createQuery( $DQL );
$results = $query->getResult();
foreach ( $results as $result ) {
    echo '<pre>';
    print_r($result->getEvent()->getId().' - photo'.$result->getId().' - '. $result->getLikes() );
    echo '</pre>';
}

请注意,我已经用学说 2 和 symfony 2.8 对此进行了测试

于 2017-09-15T06:57:37.050 回答
0

在您的查询中,您要加入 ss.Id 但您尚未在子查询中选择该列,因此 ss.id 不存在。此外,您的内部联接是您称为 p2.event e2 的表。我认为您只打算用于“事件 e2”

SELECT p.id
FROM Photo p
INNER JOIN (
            SELECT p2.likes, e2.id
            FROM Photo p2
            INNER JOIN event e2
            GROUP BY e2.id
           ) ss ON ( p.event_id = ss.id AND p.likes = ss.likes )

这里唯一的变化是我将 e2.id 添加到您的子查询选择中。此查询仍然无法解决您的问题。你想要最喜欢的那个。所以你应该把 p2.likes 变成 MAX(p2.likes)

SELECT p.id
FROM Photo p
INNER JOIN (
            SELECT MAX(p2.likes) AS Likes, e2.id
            FROM Photo p2
            INNER JOIN event e2
            GROUP BY e2.id
           ) ss ON ( p.event_id = ss.id AND p.likes = ss.likes )

此外,考虑如果两张图片与喜欢相关,您将使用此查询返回两个结果。您可能会考虑使用 CROSS APPLY(假设 DQL 有它)来避免这样的事情。

SELECT e.id, p.id
FROM Events E
CROSS APPLY (
              SELECT TOP 1 p.id
              FROM photos p 
              WHERE p.event_id = e.id
              ORDER BY Likes DESC 
            ) p
于 2013-04-23T15:51:02.190 回答
0

不是 DQL 专家,但如果您避免使用聚合函数,则始终可以使用SQL Select only rows with Max Value on a Column中描述的第二种方法:

select p1.*
from photos p1
left outer join photos p2
on (p1.event_id = p2.event_id and p1.likes < p2.likes)
where p2.event_id is null;
于 2013-04-23T15:55:26.383 回答