![]() |
|
|
| Subject:
how do I limit left joins in mysql?
Category: Computers > Programming Asked by: hish-ga List Price: $50.00 |
Posted:
01 Nov 2004 04:50 PST
Expires: 15 Nov 2004 01:54 PST Question ID: 422861 |
I try to limit left joins or subselects on mysql 4.1. Example: table t1 a1 | b1 -------------- 1 | 11 2 | 21 3 | 31 4 | 41 table t2 a2 | b2 -------------- 2 | 51 2 | 61 2 | 71 4 | 81 table t3 a3 | b3 -------------- 1 | 151 1 | 161 3 | 171 3 | 181 when I want to retrieve the first 3 records of t1: select * from t1 limit 0,3 result: a1 | b1 -------------- 1 | 11 2 | 21 3 | 31 Example A: but now I want to retrieve the first 3 records of t1 and t2.b2 and when there is a match, also the first of t1: expected result: a1 | b1 | b2 ------------------- 1 | 11 | null 2 | 21 | 51 3 | 31 | null Example B: or with 3 tables, I want t1, t2.b2 and t3.b3 expected result: a1 | b1 | b2 | b3 ---------------------------- 1 | 11 | null | 151 2 | 21 | 51 | null 3 | 31 | null | 171 I have no idea how to do a query for examples A and B. Also be aware that the tables might have thousands of similiar records. So, when for example t2.a2 and t3.a3 has 10000 entries with the value "1" and we would do a distinct left join, then we would crash the db because it would try to filter 10000x10000 rows, even when we only need the first match. | |
| |
| |
| |
|
|
| There is no answer at this time. |
|
| Subject:
Re: how do I limit left joins in mysql?
From: mathtalk-ga on 01 Nov 2004 07:27 PST |
I suspect that outer joins characteristically do not allow a (further) restriction on the table/field which is "optional". One approach to try: construct the "outer join" instead as a UNION: those records from the required table for which no match exists (a not exists clause) in the optional table, padded with Nulls for fields from the latter, combined with a query that does an inner join (and restricts the match to only the "first" row as you define it in the "optional" table). UNION was implemented in MySQL starting with version 4.0. regards, mathtalk-ga |
| Subject:
Re: how do I limit left joins in mysql?
From: mathtalk-ga on 04 Nov 2004 11:11 PST |
Let's consider the Example A above, in which there are two tables, t1 and t2.
The more complex of the two queries is where a match exists in t2.a2
to t1.a1, because we need to pick out the least/first t2.b2 that
works. There are several approaches for doing this, and no one
approach is always the best performer. But one that often works
nicely for me is this:
SELECT t1.a1, t1.b1, t2.b2 from t1, t2
where t1.a1 = t2.a2
and not exists ( select * from t2 x2
where a2 = t2.a2
and b2 < t2.b2
)
The easier of the two queries is the one in which a t1 row has no
matching t2 row. We might write (anticipating the "missing" field):
SELECT t1.a1, t1.b1, Null from t1
where not exists ( select * from t2
where a2 = t1.a1
)
Finally, put both queries together:
SELECT t1.a1, t1.b1, t2.b2 from t1, t2
where t1.a1 = t2.a2
and not exists ( select * from t2 x2
where a2 = t2.a2
and b2 < t2.b2
)
UNION ALL
SELECT t1.a1, t1.b1, Null from t1
where not exists ( select * from t2
where a2 = t1.a1
)
I'm using UNION ALL here because we know a priori that the rows from
these two queries are disjoint; it seems a waste of server time to
look for duplicates and weed them out.
regards, mathtalk-ga |
| Subject:
Re: how do I limit left joins in mysql?
From: hish-ga on 05 Nov 2004 00:33 PST |
Hi mathtalk-ga, thanks for your comment. I tried it with 10000 records in t1 and 100 in t2. I have two problems with your approach: a) In every case your query should return exactly 10000 rows regardless what values are in in the fields but I always get >10000 b) doing a select * on t1 takes about 0.5 secs. doing a left join or a t1.a1=t2.a2 takes about 0.8 secs. Your query takes about 3.8 secs. c) "... not exists ( select * from t2 x2" what does "x2" mean here? Thanks for your help |
| Subject:
Re: how do I limit left joins in mysql?
From: mathtalk-ga on 05 Nov 2004 05:38 PST |
hish-ga wrote:
a) In every case your query should return exactly 10000 rows
regardless what values are in in the fields but I always get >10000
You are guaranteed of exactly 10000 rows if (as was the case in
Example A) the composite key a2,b2 is unique on table t2. When two
rows have the same "least" value b2 for a shared a2, the query I wrote
will return both. This is my best guess as to why there are more than
10000 rows returned. Let me know if that's the "real world"
situation.
b) doing a select * on t1 takes about 0.5 secs. doing a left join or a
t1.a1=t2.a2 takes about 0.8 secs. Your query takes about 3.8 secs.
The sort of query I wrote does more work than a simple join (inner or
outer) because it locates the minimum b2 for given a2. I'd think in
terms of getting a query that returns the correct results and then
tuning performance.
c) "... not exists ( select * from t2 x2"
what does "x2" mean here?
Here x2 is an "alias" for table t2 in the dependent subquery.
Although I allowed the fields belonging to the "inner" copy of t2 to
be so identified by leaving off the table qualification, the alias x2
would be used explicitly in this manner:
SELECT t1.a1, t1.b1, t2.b2 from t1, t2
where t1.a1 = t2.a2
and not exists ( select * from t2 x2
where x2.a2 = t2.a2
and x2.b2 < t2.b2
)
regards, mathtalk-ga |
If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you. |
| Search Google Answers for |
| Google Home - Answers FAQ - Terms of Service - Privacy Policy |