Yes, your queries can certainly use refactoring. Using two separate calls on the same table is asking MySQL to do needless extra work.
To convert your queries into plain English, you want to:
- create a result set of
containertype1
values sorted by SubmissionId
- for each
SubmissionId
from FormId
28
- including only submissions that contain a
Status1
value of Pending
.
The cleanest, most direct way to perform this task is with a "pivot" technique.
Raw Query (untested):
SELECT
MAX(CASE WHEN FieldName = 'containertype1' THEN FieldValue ELSE NULL END)
FROM `#__rsform_submission_values`
WHERE FormId = 28
GROUP BY SubmissionId
HAVING MAX(CASE WHEN FieldName = 'Status1' THEN FieldValue ELSE NULL END) = 'Pending'
ORDER BY SubmissionId
GROUP BY
creates "aggregate data" for each unique SubmissionId
. Extracting specific details from within this collection of consolidated rows requires specialized calls (e.g.MAX(CASE...)
).
The HAVING
clause requires SubmissionIds to contain a row with a FieldName
of Status1
and a FieldValue
value of Pending
. This relies on the fact that your submission_values table does not allow a SubmissionId to have 2 or more Status1
rows.
For every qualifying SubmissionId, the result set will provide the value that is stored with containertype1
. If the qualifying SubmissionId does not have a containertype1
row, a NULL
value will be provided as the default (you could change NULL
to No Container Type
if you wanted).
PHP/Joomla Syntax (untested):
$query = $db->getQuery(true)
->select("MAX(CASE WHEN FieldName = 'containertype1' THEN FieldValue ELSE NULL END)")
->from("#__rsform_submission_values")
->where("FormId = 28")
->group("SubmissionId")
->having("MAX(CASE WHEN FieldName = " . $db->q("status") . " THEN FieldValue ELSE NULL END) = " . $db->q("pending"));
// echo $query->dump(); // uncomment if you want to confirm the rendered query
try {
$db->setQuery($query);
echo "<pre>";
var_dump($db->loadColumn());
} catch (Exception $e) {
JFactory::getApplication()->enqueueMessage("Query Syntax Error: " . $e->getMessage(), 'error'); // never show getMessage() to public
}
If you would like to see this technique in other contexts, here are some other pivot solutions that I have posted: