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 to retrieve the last 5 rows corresponding in tableB (ordered by idB).
I've tried
SELECT * FROM tableA INNER JOIN tableB ON tableA.idA = tableB.idA LIMIT 5
but it's just limiting the global result of INNER JOIN whereas I want to limit the result for each different tableA.id
How can I do that ?
Thanks
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
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...
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
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)