#mysql
#mysql
Вопрос:
У меня есть требование получить значения sum, avg, count как 0 после имени учреждения, когда дата lr.processed_on не совпадает с датой ввода. как я могу добиться этого в следующем запросе
SELECT bd.id as institutionId, bd.institution_name as institution, count(lr.id) as numberOfTransaction, sum(lr.amount) as totalTransactionAmount, avg(lr.amount) as averageTransactionAmount, sum(lr.processing_fee) as totalProcessingFee from daily_transaction lr join ( select s.id from status s where s.name not in (:statusName)) s on lr.customer_status = s.id join account sa on lr.account = sa.id join branch b on sa.branch = b.id right join institution_details bd on b.institution = bd.id join status s2 on bd.status = s2.id where (:institutionIdParam is null or bd.id = :institutionIdParam) and (:instutionStatus is null or s2.description = :instutionStatus) and (:fromDate is null and :toDate is null or cast(lr.processed_on as date) lt;= :toDate and cast(lr.processed_on as date) gt;= :fromDate) group by bd.id , bd.institution_name order by bd.institution_name asc;
Комментарии:
1. Можете ли вы поместить в свой пост образцы входных и выходных данных, чтобы лучше понять вопрос?
2. если я помещу ввод, который не является lr.обработанным, то вывод будет пустым, но я хочу получить результат в виде 0 транзакций для всех деталей в выводе
Ответ №1:
Цель использования RIGHT JOIN для institution_details, по-видимому, состоит в том, чтобы вы хотели, чтобы все учреждения были перечислены независимо от их ежедневных транзакций. Для тех учреждений, где нет ежедневных транзакций, processed_on рассматривается как имеющий НУЛЕВОЕ значение (именно так будет вести себя правильное соединение), и условие WHERE, подобное вашему, вернет значение false, а затем отфильтруются данные institution_details.
Вы можете преодолеть это, переместив предложение проверки параметров в условие соединения, например так:
right join institution_details bd on b.institution = bd.id and ((:fromDate is null and :toDate is null) or (cast(lr.processed_on as date) lt;= :toDate and cast(lr.processed_on as date) gt;= :fromDate))
и убираем его из пункта «ГДЕ«.
Обратите внимание на скобки, которые я добавил в ваше выражение; в присутствии операторов OR и AND нам необходимо учитывать приоритет операторов и порядок вычисления, было бы неправильно (на мой взгляд) не иметь этих скобок. Даже при этом вам необходимо предотвратить ситуацию, когда предоставляется только один (но не оба) параметра :FromDate и :ToDate.