views:

323

answers:

4

I'm running a simple query with a join, similar to

SELECT t1.a, t2.b FROM t1 LEFT JOIN t2 ON ... LIMIT 5

As t1 has-many rows in t2 ( any number above 2 ) the LIMIT statement does not return the first 5 rows from t1 and corresponding entries from t2, but 5 rows which usually include 2-3 rows from t1.

How can I write this query to get the first 5 rows from t1 and the corresponding entries from t2?


Using MySQL 5.0.45.

A: 

I believe the following will do the trick:

SELECT t1.a, (SELECT t2.b FROM t2 WHERE t2... = t1...) AS b FROM t1 LIMIT 5
Anax
Thanks for the answer. As there are multiple entries in t2 corresponding to t1, I get `ERROR 1242 (21000): Subquery returns more than 1 row`.
Robert Munteanu
+3  A: 
SELECT t3.a, t2.b FROM (SELECT * FROM t1 LIMIT 5) t3
LEFT JOIN t2 ON ...

Note that if you use limit without an 'order by' clause, it is not defined which 5 rows you will get. Consider adding an 'order by' clause if this is not what you want.

Mark Byers
Please note, this solution has scalability issues with MySQL, as well as not working if he desires to ORDER BY a field in t2.
hobodave
@hobodave Luckily, I `ORDER BY` a field in t1.
Robert Munteanu
@Robert: You might find that you need to apply the ORDER BY twice - once inside the inner query to select the first five rows, and then again in the outer query to ensure the results are returned in the same order.
Mark Byers
+1  A: 

This is a classic pagination query. I suggest breaking it down into two queries:

SELECT DISTINCT t1.id FROM t1 LEFT JOIN t2 ON ... LIMIT 5

Take these id's and place them in the following query:

SELECT t1.a, t2.b FROM t1 LEFT JOIN t2 ON ... WHERE t1.id IN (?,?,?,?,?) 
hobodave
Thanks for the answer. A 1-query solution is preferrable, and has been provided.
Robert Munteanu
np, just be aware of the performance implications of the derived table solution as well as the SELECT *.
hobodave
That's a good point as well. Right now the derived table needs to look at ~8k rows, and it's fast enough. Also, I wont' use `SELECT *`.
Robert Munteanu
A: 

You can group it by the unique column in t1:

SELECT * FROM t1 JOIN t2 ON ... GROUP BY t1.id LIMIT 5

But do you need the t2 table to be in a specific order?

Timothy
Thanks for the answer. Please look at my question, I need more than 5 rows returned, it's 10+ rows from t2 coupled with _exactly_ 5 rows from t1. The accepted answer has a good solution. hobodave's one also works.
Robert Munteanu
ah yes - makes sense, didn't read the question properly. Accepted answer works well. You could also do it with variables that count the unique rows but that gets messy.
Timothy