DQL Select every rows having one column's MAX value

后端 未结 3 1928
囚心锁ツ
囚心锁ツ 2021-01-03 05:28

Working with Symfony 2 and Doctrine, I\'m searching for a way to select every rows having the max value in a specific column.

Right now, I\'m doing it in two queries

相关标签:
3条回答
  • 2021-01-03 06:08

    For me when i trying to make a subquery i make:

    ->andWhere($qb->expr()->eq('affaire', $qb2->getDql()));
    
    0 讨论(0)
  • 2021-01-03 06:11

    After some hours of headache and googling and stackOverflow readings... I finally found out how to make it.

    Here is my final DQL queryBuilder code:

        $qb = $this->createQueryBuilder('a');
        $qb2= $this->createQueryBuilder('mss')
                ->select('MAX(mss.periodeComptable) maxPeriode')
                ->where('mss.affaire = a')
                ;
    
        $qb ->innerJoin('GAAffairesBundle:MontantMarche', 'm', 'WITH', $qb->expr()->eq( 'm.periodeComptable', '('.$qb2->getDQL().')' ))
            ->where('a = :affaire')
            ->setParameter('affaire', $affaire)
            ;
    
        return $qb->getQuery()->getResult();
    
    0 讨论(0)
  • 2021-01-03 06:23

    To achieve this using pure DQL and without use of any aggregate function you can write doctrine query as

    SELECT a
    FROM GAAffairesBundle:MontantMarche a
        LEFT JOIN GAAffairesBundle:MontantMarche b
        WITH a.affaire = b.affaire 
        AND a.periodeComptable < b.periodeComptable
    WHERE b.affaire IS NULL
    ORDER BY a.periodeComptable DESC
    

    The above will return you max record per group (per affaire)

    Expalnation

    The equivalent SQL for above DQL will be like

    SELECT a.*
    FROM MontantMarche a
    LEFT JOIN MontantMarche b 
        ON a.affaire = b.affaire 
        AND a.periodeComptable < b.periodeComptable
    WHERE b.affaire IS NULL
    ORDER BY a.periodeComptable DESC
    

    Here i assume there can be multiple entries in table e.g(MontantMarche) for each affaire, so here i am trying to do a self join on affaire and another tweak in join is i am trying to join only rows from right table(b) where a's periodeComptable < b's periodeComptable, So the row for left table (a) with highest periodeComptable will have a null row from right table(b) thus to pick the highest row per affaire the WHERE right table row IS NULL necessary.

    Similarly using your posted sample query with inner join can be written as

    select yt.id, yt.rev, yt.contents
    from YourTable yt
    left join YourTable ss on yt.id = ss.id and yt.rev < ss.rev
    where ss.rev is null
    

    Hope it makes sense

    0 讨论(0)
提交回复
热议问题