Mysql 使用左联接避免三个表中的笛卡尔积
我有以下三个表格:-Mysql 使用左联接避免三个表中的笛卡尔积,mysql,join,Mysql,Join,我有以下三个表格:- 客户(客户id、名称) 已完成(已完成id、客户id、已完成) 目标(目标id、客户id、目标) 在编写以下查询时,由于笛卡尔积,我得到了错误的输出:- SELECT C.name customer, SUM(A.achieved) achived, SUM(T.target) target FROM customers C LEFT JOIN achieved A ON C.customer_id = A.customer_id LEFT JOIN target T ON
SELECT C.name customer, SUM(A.achieved) achived, SUM(T.target) target
FROM customers C
LEFT JOIN achieved A
ON C.customer_id = A.customer_id
LEFT JOIN target T
ON C.customer_id = T.customer_id
GROUP BY customer
使用LEFT join获得正确结果的正确方法是什么?您也可以尝试一下
SELECT C.name customer, SUM(A.achieved) achived, SUM(T.target) target
FROM customers C,achieved A,target T
WHERE C.customer_id = A.customer_id
AND C.customer_id = T.customer_id
AND A.customer_id = T.customer_id
GROUP BY C.customer
我理解,因为您将
已实现
和目标
都加入到客户
,所以您得到的是已实现
和目标
的无意义笛卡尔积
您可以暂时删除SUM
,查看问题的原因。
如果没有SUM
,此查询将为您提供不必要的大结果集。使用SUM
,重复的值都会对求和产生影响,从而产生一个大于预期的值
通过连接一个常量序列,可以强制MySQL将连接的表分开,如下所示
SELECT C.name customer, SUM(A.achieved) achieved, SUM(T.target) target
FROM customers C
# Split every customer into two rows, joinType=1 vs. joinType=2
LEFT JOIN (SELECT 1 AS joinItem UNION ALL SELECT 2) AS joinItems
ON TRUE
# Join achieved only where joinType=1 (will be NULL elsewhere)
LEFT JOIN achieved A
ON joinItem = 1 AND C.customer_id = A.customer_id
# Join target only where joinType=2 (will be NULL elsewhere)
LEFT JOIN target T
ON joinItem = 2 AND C.customer_id = T.customer_id
GROUP BY customer
现在,已实现目标和目标将不再相乘
EXPLAIN
应确认此问题仍然得到有效处理
注意:最初,这会为每个匹配的“已实现”(目标数据为空)创建一个客户记录,并为每个匹配的“目标”(目标数据为空)创建一个单独的客户记录。然而,在这种情况下,
分组依据
会将每个客户的数据重新组合成一个记录,并提供我们想要的数据。从这个意义上讲,输出是错误的?您期望的输出是什么?为您的模式和示例数据提供sqlfiddle.com链接这不会产生与左连接相同的结果;它将排除没有任何目标或已实现(sic)记录的客户。