将多个 mysql 查询重构为 1
Refactoring multiple mysql queries into 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
table)。如果没有找到这个任务的邮件记录,那么我仍然想显示它(所以另一个正确的加入是不可能的。
我还需要对 fusion_response
table 执行相同的操作,以检查客户是否已发送回复。如果他们还没有那么我仍然想显示任务。
显然我知道我可以通过 运行 主 select 查询中的一个查询来实现这一点,但这在我的脑海中并不合适。有没有一种方法可以在 1 个查询中执行此操作?
谢谢。
将您的查询结构更改为仅使用左联接 - 与右联接本质上相同,但不必在左右联接之间交换。
你把客户加入维修的事实告诉我客户是主要的table所以现在我们可以说从客户那里得到一切,如果有记录就加入维修。
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
这里我们可以使用left outer join来查看是否有邮件,如果没有,则不删除该行,与response相同
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条维修记录就有5条记录。你只是想要一个 yes/no 打勾只是说他们有然后也许主 select 中的一个相关子查询实际上是你想要的或者一个分组并计算一个案例中的邮件数量来打勾。
让我知道你想要什么作为完成查询的输出。
编辑:
我已对查询进行了更新,以考虑您提供给我的信息。请注意,我不知道你想如何输出最终结果,所以我只是猜测!让我知道这是否解决了问题,否则请重新设计!
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
我目前正在开发一个为客户生成各种报告的系统,我需要指明方向才能实现我的需要。
目前的情况是我需要对未完成的任务进行概述(以及关于剩余任务的一些细节)。
到目前为止,我已经创建了所有任务的列表(包括有关客户的信息),这是在以下查询中实现的:
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
table)。如果没有找到这个任务的邮件记录,那么我仍然想显示它(所以另一个正确的加入是不可能的。
我还需要对 fusion_response
table 执行相同的操作,以检查客户是否已发送回复。如果他们还没有那么我仍然想显示任务。
显然我知道我可以通过 运行 主 select 查询中的一个查询来实现这一点,但这在我的脑海中并不合适。有没有一种方法可以在 1 个查询中执行此操作?
将您的查询结构更改为仅使用左联接 - 与右联接本质上相同,但不必在左右联接之间交换。
你把客户加入维修的事实告诉我客户是主要的table所以现在我们可以说从客户那里得到一切,如果有记录就加入维修。
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
这里我们可以使用left outer join来查看是否有邮件,如果没有,则不删除该行,与response相同
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条维修记录就有5条记录。你只是想要一个 yes/no 打勾只是说他们有然后也许主 select 中的一个相关子查询实际上是你想要的或者一个分组并计算一个案例中的邮件数量来打勾。
让我知道你想要什么作为完成查询的输出。
编辑:
我已对查询进行了更新,以考虑您提供给我的信息。请注意,我不知道你想如何输出最终结果,所以我只是猜测!让我知道这是否解决了问题,否则请重新设计!
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