Рефакторинг нескольких запросов MySQL в 1

В настоящее время я разрабатываю систему, которая генерирует различные отчеты для клиента, и мне нужно указывать направление, чтобы достичь того, что мне нужно.

Текущая ситуация такова, что мне нужно подготовить обзор задач, которые еще не выполнены (и некоторые подробности о том, что осталось).

Пока что я создал список всех задач (включая информацию о клиенте), это было достигнуто в следующем запросе:

SELECT `fusion_repairs`.*, `fusion_customers`.*
FROM `fusion_repairs`
RIGHT JOIN `fusion_customers`
ON `fusion_repairs`.`customer_id` = `fusion_customers`.`customer_id`
ORDER BY `fusion_repairs`.`repair_id`
DESC LIMIT 20

В идеале мне нужно иметь возможность проверить, было ли клиенту по электронной почте о задаче (fusion_mail Таблица). Если для этой задачи не найдено ни одной записи почты, я все же хочу показать ее (так что о другом правом присоединении не может быть и речи.

Мне также нужно сделать то же самое с fusion_response таблица, чтобы проверить, отправил ли клиент ответ. Если нет, то я все равно хочу отобразить задачу.

Очевидно, я знаю, что могу добиться этого, запустив запрос в основном запросе select, но это не очень хорошо в моей голове. Есть ли способ сделать это в 1 запрос?

Диаграмма отношений сущностей
Спасибо.

1

Решение

Измените структуру запроса, чтобы использовать только левые соединения — по сути, то же самое, что и правое соединение, но при этом не нужно переключаться между левым и правым соединением.

Тот факт, что вы правильно присоединили клиентов к ремонту, говорит мне, что клиенты — это главная таблица, так что теперь мы можем сказать, что мне все нужно от клиентов, присоединяйтесь к ремонту, если запись существует.

SELECT `fusion_repairs`.*, `fusion_customers`.*
FROM   `fusion_customers`
LEFT OUTER JOIN `fusion_repairs` ON `fusion_repairs`.`customer_id` = `fusion_customers`.`customer_id`
ORDER BY `fusion_repairs`.`repair_id`
DESC LIMIT 20

Здесь мы можем использовать левое внешнее соединение, чтобы увидеть, есть ли у нас почта, если нет, не удалять строку и то же самое с ответом.

SELECT `fusion_repairs`.*, `fusion_customers`.*
FROM   `fusion_customers`
LEFT OUTER JOIN `fusion_repairs` ON `fusion_repairs`.`customer_id` = `fusion_customers`.`customer_id`
LEFT OUTER JOIN `fusion_mail` ON `fusion_mail`.`repair_id` = `fusion_repairs`.`repair_id`
LEFT OUTER JOIN `fusion_response` ON `fusion_response`.`repair_id` = `fusion_repairs`.`repair_id`
ORDER BY `fusion_repairs`.`repair_id`
DESC LIMIT 20

Теперь мой вопрос .. Что вы хотите вернуть? Если имеется 5 почтовых записей, то будет 1 запись для 1 ремонтной записи. Хотите ли вы просто поставить галочку «да / нет», просто чтобы сказать, что у них, возможно, есть коррелированный подзапрос в главном выборе, на самом деле то, что вы хотите, или сгруппировать и подсчитать количество писем внутри дела, чтобы отметить.

Дайте мне знать, что вы хотите в качестве вывода для завершения запроса.

РЕДАКТИРОВАТЬ:

Я обновил запрос, чтобы учесть предоставленную вами информацию. Обратите внимание, я понятия не имею, как вы хотите вывести окончательный результат, поэтому я просто сделал предположение! Дайте мне знать, если это решит это иначе, вернемся к чертежной доске для меня!

SELECT  fusion_repairs.*,
fusion_customers.*,
CONCAT( CASE WHEN fusionMail.mail_type_A > 0 THEN 'displayA' ELSE '' END,
CASE WHEN fusionMail.mail_type_B > 0 THEN 'displayB' ELSE '' END,
CASE WHEN fusionMail.mail_type_C > 0 THEN 'displayC' ELSE '' END) as email_font_awesome_icon,
CONCAT( CASE WHEN fusionResponse.response_status_A > 0 THEN 'displayA' ELSE '' END,
CASE WHEN fusionResponse.response_status_B > 0 THEN 'displayB' ELSE '' END,
CASE WHEN fusionResponse.response_status_C > 0 THEN 'displayC' ELSE '' END) as response_font_awesome_icon
FROM    fusion_customers
LEFT OUTER JOIN fusion_repairs ON fusion_repairs.customer_id = fusion_customers.customer_id
LEFT OUTER JOIN (
SELECT  repair_id,
SUM(CASE WHEN mail_type = 1 THEN 1 else 0 END) AS mail_type_A,
SUM(CASE WHEN mail_type = 2 THEN 1 else 0 END) AS mail_type_B,
SUM(CASE WHEN mail_type = 3 THEN 1 else 0 END) AS mail_type_C
FROM fusion_mail
GROUP BY repair_id
) fusionMail ON fusionMail.repair_id = fusion_repairs.repair_id
LEFT OUTER JOIN (
SELECT  repair_id,
SUM(CASE WHEN response_status = 1 THEN 1 else 0 END) AS response_status_A,
SUM(CASE WHEN response_status = 2 THEN 1 else 0 END) AS response_status_B,
SUM(CASE WHEN response_status = 3 THEN 1 else 0 END) AS response_status_C
FROM fusion_response
GROUP BY repair_id
) fusionResponse ON fusionResponse.repair_id = fusion_repairs.repair_id
1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector