Получать первые/последние n записей на группу по

У меня есть две таблицы: tableA (idA, titleA) и tableB (idB, idA, textB) с отношением от одного до многих между ними. Для каждой строки в таблице A я хочу получить последние 5 строк, соответствующих таблице B (упорядочен по idB).

Я пробовал

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

но это просто ограничивает глобальный результат INNER JOIN, тогда как я хочу ограничить результат для каждой другой таблицыA.id

Как я могу это сделать?

Спасибо

Ответ 1

Я думаю, что это то, что вам нужно:

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

Много упрощенное и исправленное решение Карлоса (его решение вернет первые 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...

Ответ 3

Убедитесь, что таблица "B" имеет индекс (idA, idB) для оптимизированного заказа по целям, поэтому для каждого идентификатора "А" он может быстро спуститься по порядку "B", тем самым поставив новейшую вершину PER EACH Идентификатор "А". Используя переменные MySQL, каждый раз, когда изменяется идентификатор "А", он сбрасывает ранг обратно на 1 для следующего идентификатора "А".

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

Ответ 4

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, если вы хотите, чтобы нижние идентификаторы убывали, если вы хотите более высокие идентификаторы)
  • менее сложный и легкий для включения большего количества условий.
  • Если верхнее предложение отсутствует в предложении ограничения использования mysql (у меня нет большого количества знаний abt mysql)