Я считаю, что нужны CASE и GROUP BY:
SELECT CASE
WHEN imgWidth = $maxImageWidth AND imgHeight = $maxImageHeight
THEN 0
WHEN imgWidth != $maxImageWidth AND imgHeight = $maxImageHeight
THEN 1
WHEN imgWidth = $maxImageWidth AND imgHeight != $maxImageHeight
THEN 2
END AS count_type,
COUNT(*) AS imgCount
FROM (SELECT imgHeight, imgWidth, imgId AS primaryId FROM primary_images
UNION ALL
SELECT imgHeight, imgWidth, primaryId FROM secondary_images
) AS union_table
WHERE primaryId = $imgId
AND (imgWidth = $maxImageWidth OR imgHeight = $maxImageHeight)
GROUP BY count_type;
По крайней мере заманчиво вставить предложение WHERE в подзапросы UNION, но оптимизатор должен это сделать в любом случае.Убедитесь, что он делает это, изучив вывод EXPLAIN.Если оптимизатор не выполняет автоматическое нажатие на предикат, вы должны написать:
SELECT CASE
WHEN imgWidth = $maxImageWidth AND imgHeight = $maxImageHeight
THEN 0
WHEN imgWidth != $maxImageWidth AND imgHeight = $maxImageHeight
THEN 1
WHEN imgWidth = $maxImageWidth AND imgHeight != $maxImageHeight
THEN 2
END AS count_type,
COUNT(*) AS imgCount
FROM (SELECT imgHeight, imgWidth, imgId AS primaryId FROM primary_images
WHERE primaryId = $imgId -- or: imgId = $imgId
AND (imgWidth = $maxImageWidth OR imgHeight = $maxImageHeight)
UNION ALL
SELECT imgHeight, imgWidth, primaryId FROM secondary_images
WHERE primaryId = $imgId
AND (imgWidth = $maxImageWidth OR imgHeight = $maxImageHeight)
) AS union_table
GROUP BY count_type;
Недостаток написанного решения состоит в том, что переменные $maxImageWidth
и $maxImageHeight
используются 4 раза каждая (и$imgId
один раз).Если вы готовите оператор, как показано (встраивая значения в строку, представляющую SQL), это не так уж плохо.Если вы используете заполнители, вам нужна схема именования для заполнителей, если это возможно (:img_ht
, :img_wd
, :img_id
(или, по крайней мере, :1
, :2
, :3
) вместо ?
заполнители), поэтому вы можете передавать каждое значение только один раз в инструкции EXECUTE.Эта возможность зависит от вашей СУБД;MySQL является одной из ряда СУБД, которые не поддерживают эту возможность.