Я не на 100% уверен в том, что вы выполняете с помощью этих запросов, поэтому я не рассматривал принципиально другой подход.Если вы можете включить пример данных, чтобы продемонстрировать свою логику, я могу взглянуть на это.Но, с точки зрения простого объединения двух ваших запросов, я могу это сделать.Прежде всего, следует соблюдать осторожность ...
SQL компилируется в планы запросов.Если план запроса для каждого запроса значительно отличается от другого, объединение их в один запрос может быть плохой идеей.В итоге вы можете получить единый план, который работает в обоих случаях, но не очень эффективен в обоих случаях.Один плохой план может быть намного хуже двух хороших планов => Более короткий, более компактный код не всегда дает более быстрый код.
Вы можете указать selected
в своем GROUP BY
вместо предложения WHERE
;тот факт, что у вас есть два UNIONed
запроса, показывает, что вы уже рассматриваете их как две отдельные группы.
Тогда единственное различие между вашими запросами - это фильтр на count(*)
, который можно согласовать сCASE WHEN
оператор ...
SELECT
groups.groupID,
groups.GroupType,
groups.max,
CASE WHEN Candies.Selected = 0 THEN count(*) ELSE 0 END as remainingNum,
CASE WHEN Candies.Selected = 0 THEN group_concat(candies.name,', ') ELSE '' END as remaining
FROM
groups
INNER JOIN
members
ON members.GroupID = groups.GroupID
INNER JOIN
candies
ON Candies.CandyID = members.CandyID
GROUP BY
Groups.GroupID,
Groups.GroupType,
Groups.max,
Candies.Selected
HAVING
CASE
WHEN Candies.Selected = 0 AND COUNT(*) <= 3 THEN 1
WHEN Candies.Selected = 1 AND COUNT(*) = Groups.Size THEN 1
ELSE 0
END
=
1
Изменения макета происходят просто потому, что я не согласен с использованием NATURAL JOIN по причинам обслуживания.Они представляют собой кратчайший путь в начальной сборке и потенциальную катастрофу в дальнейшей разработке.Но это другая проблема, вы можете прочитать об этом онлайн, если захотите.