Reputation: 343
I've got this query which is quite specific and returns exactly what I need. As we know, nested queries in mysql can be pretty terrible in terms of runtime. If anyone could help me convert the following code to a JOIN
statement, I would really appreciate it.
Any other optimizations are welcome and encouraged, of course.
SELECT title
FROM exp_channel_titles
WHERE entry_id IN (SELECT rel_child_id
FROM exp_relationships
WHERE rel_id IN (SELECT field_id_202
FROM exp_channel_data
WHERE entry_id = 19971));
Thank you!
Upvotes: 7
Views: 1695
Reputation: 108460
Another alternative:
SELECT t.title
FROM exp_channel_titles t
JOIN ( SELECT r.rel_child_id
FROM exp_relationships r
JOIN exp_channel_data d
ON d.field_id_202 = r.rel_id
WHERE d.entry_id = 19971
GROUP BY r.rel_child_id
) c
ON c.rel_child_id = t.entry_id
This query still includes an inline view (or "derived table", in MySQL lingo), but this query will return a resultset equivalent to the original query, without introducing or eliminating any "duplicate" titles from/in the exp_channel_titles table.
Note that other solutions may introduce duplicates, due to the nature of the way the JOIN handles one-to-many relationships. You can avoid returning any duplicates that are introduced by using a DISTINCT keyword or a GROUP BY clause, but this will also eliminate any duplicates that were being returned in the original query.
Upvotes: 2
Reputation: 162831
select t.title
from exp_channel_titles as t
inner join exp_relationships as r
on r.rel_child_id = t.entry_id
inner join exp_channel_data as d
on d.field_id_202 = r.rel_id
and d.entry_id = 19971;
Upvotes: 1
Reputation: 86765
SELECT DISTINCT
titles.title
FROM
exp_channel_titles AS titles
INNER JOIN
exp_relationships AS rel
ON titles.entry_id = rel.rel_child_id
INNER JOIN
exp_channel_data AS channel
ON rel.rel_id = channel.field_id_202
WHERE
channel.entry_id = 19971
The DISTINCT is there incase you have many:many relationships, etc, that may otherwise create duplicates.
In terms of optimisations, ensure each table has indexes on the fields that you use in JOINs and WHERE clauses.
Upvotes: 4