获取每组的前/后n条记录

时间:2012-04-17 12:37:26

标签: mysql sql inner-join greatest-n-per-group

我有两个表:tableA (idA, titleA)tableB (idB, idA, textB),它们之间有一对多关系。对于tableA中的每一行,我想检索tableB中对应的最后5行(由idB排序)。

我试过

SELECT * FROM tableA INNER JOIN tableB ON tableA.idA = tableB.idA LIMIT 5

但它只是限制了INNER JOIN的全局结果,而我想限制每个不同tableA.id的结果。

我该怎么做?

由于

4 个答案:

答案 0 :(得分:5)

很多简化和纠正的卡洛斯解决方案(他的解决方案将返回前5行,而不是最后......):

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

在MySQL中,即使它是逐个查询,您也可以使用tB1.textB,因为您要按第一个表中的idB进行分组,因此每个组只有tB1.textB的单个值。 ..

答案 1 :(得分:2)

我认为这就是你所需要的:

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

此处有关此方法的更多信息:

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

答案 2 :(得分:0)

确保您的“B”表在(idA,idB)上有一个索引,以便按目的优化顺序,因此对于每个“A”ID,它可以快速地使“B”顺序下降,从而将最新的PER到每个PER “援助。使用MySQL变量,每次“A”ID改变时,它会将等级重置为1,以便下一个“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

答案 3 :(得分:0)

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)
  • (如果你想要更高的ID,你想要更低的id desc)
  • 不那么复杂,容易包含更多条件
  • 如果mysql使用限制子句中没有top子句(我没有太多的知识abt mysql)