I have two MySQL queries. The first one returns a list of codes, which comprise either one or two letters (e.g. "AB", "WO", "G"). This is the query:
SELECT d.field_id_105 AS code,
title
FROM exp_channel_titles AS t
INNER JOIN exp_channel_data AS d ON (d.entry_id = t.entry_id)
WHERE t.channel_id = 18
AND t.status = 'open'
AND t.author_id = 123
ORDER BY t.entry_id ASC
Then, using a PHP foreach loop, I'm looping through each of those codes and performing a second query on each one, which is obviously incredibly inefficient.
The second query varies slightly depending on whether the code comprises one or two letters. If it comprises 2 letters, I simply want to find all records where a specific field starts with those two letters. If it comprises one letter, I want to find all records where a specific field starts with that letter followed by any number from 1 to 9 (e.g. G1 or W8).
Here are the two different versions of the second query:
If the code comprises two letters
SELECT t.title AS title,
t.entry_date AS entry_date,
t.entry_id AS entry_id,
i.title AS installer,
i.entry_id AS installer_id,
d.entry_id
FROM exp_channel_data AS d
INNER JOIN exp_relationships AS r ON (r.parent_id = d.entry_id AND r.field_id = 48)
INNER JOIN exp_channel_titles AS t ON (d.entry_id = t.entry_id AND t.status = 'open')
INNER JOIN exp_channel_titles AS i ON (r.child_id = i.entry_id AND i.status = 'open')
WHERE LEFT(field_id_56, 2) = 'AB'
AND d.channel_id = 12
If the code comprises one letter:
SELECT t.title AS title,
t.entry_date AS entry_date,
t.entry_id AS entry_id,
i.title AS installer,
i.entry_id AS installer_id,
d.entry_id
FROM exp_channel_data AS d
INNER JOIN exp_relationships AS r ON (r.parent_id = d.entry_id AND r.field_id = 48)
INNER JOIN exp_channel_titles AS t ON (d.entry_id = t.entry_id AND t.status = 'open')
INNER JOIN exp_channel_titles AS i ON (r.child_id = i.entry_id AND i.status = 'open')
WHERE LEFT(field_id_56, 2) IN ('G1','G2','G3','G4','G5','G6','G7','G8','G9')
AND d.channel_id = 12
I've 'hard-coded' the values in the WHERE clauses for demo purposes, but they would actually be populated dynamically by PHP.
So essentially what I'd like to do is combine all of these queries into one query. I'm not sure if that's even possible. I got as far as using the first query as a subquery inside the LEFT() function, but I'm getting a little out of my depth at that point and can't work out how to handle appending the numbers to the single-letter codes. Maybe some REGEXP, but I'm not sure.
Any help appreciated, thanks.
AB
,WO
andG
. I would then run q2 once for "AB" and once for "WO". And I would run q3 once forIN ('G1', ... 'G9')
. I have tried using some PHP to create an array of all values and putting them in a single IN clause, e.g.IN ('AB','WO','G1','G2',...'G'9)
and doing away with q2 altogether, but that didn't improve performance.LEFT(field_id_56, 2) = 'AB'
and in the second time:LEFT(field_id_56, 2) = 'WO'
, is that correct? Another question, if first character in field_id_56 is 'G' can the second character be something other than '0' - '9'?