Get first/last n records per group by

后端 未结 4 2057
傲寒
傲寒 2021-01-01 00:12

I have two tables : tableA (idA, titleA) and tableB (idB, idA, textB) with a one to many relationship between them. For each row in tableA, I want

相关标签:
4条回答
  • 2021-01-01 00:25

    I think this is what you need:

    SELECT tableA.idA, tableA.titleA, temp.idB, temp.textB
    FROM tableA
    INNER JOIN
    (
        SELECT tB1.idB, tB2.idA,
        (
            SELECT textB
            FROM tableB
            WHERE tableB.idB = tB1.idB
        ) as textB
        FROM tableB as tB1
            JOIN tableB as tB2
                ON tB1.idA = tB2.idA AND tB1.idB >= tB2.idB
        GROUP BY tB1.idA, tB1.idB
        HAVING COUNT(*) <= 5
        ORDER BY idA, idB
    ) as temp
    ON tableA.idA = temp.idA
    

    More info about this method here:

    http://www.sql-ex.ru/help/select16.php

    0 讨论(0)
  • 2021-01-01 00:25
    select * from tablea ta, tableb tb
    where ta.ida=tb.idb and tb.idb in 
    (select top 5 idb from tableB order by idb asc/desc)
    
    • (asc if you want lower ids desc if you want higher ids)
    • less complicated and easy to include more conditions
    • if top clause is not present in mysql use limit clause (I don't have much knowledge abt mysql)
    0 讨论(0)
  • 2021-01-01 00:26

    Ensure your "B" table has an index on ( idA, idB ) for optimized order by purposes so for each "A" ID, it can quickly have the "B" order descending thus putting the newest to the top PER EACH "A" ID. Using the MySQL variables, every time the "A" ID changes, it resets the rank back to 1 for the next "A" id.

    select 
          B.idA,
          B.idB,
          B.textB
          @RankSeq := if( @LastAGroup = B.idA, @RankSeq +1, 1 ) ARankSeq,
          @LastAGroup := B.idA as ignoreIt
       from
          tableB B
             JOIN tableA A
                on B.idA = A.idA,
          (select @RankSeq := 0, @LastAGroup := 0 ) SQLVars 
       having
          ARankSeq <= 5
       order by
          B.idA,
          B.idB DESC
    
    0 讨论(0)
  • 2021-01-01 00:42

    Much simplified and corrected Carlos solution (his solution would return first 5 rows, not last...):

    SELECT tB1.idA, tB1.idB, tB1.textB
    FROM tableB as tB1
        JOIN tableB as tB2
            ON tB1.idA = tB2.idA AND tB1.idB <= tB2.idB
    GROUP BY tB1.idA, tB1.idB
    HAVING COUNT(*) <= 5
    

    In MySQL, you may use tB1.textB even if it is group by query, because you are grouping by the idB in the first table, so there is only single value of tB1.textB for each group...

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