从您的问题中很难判断您的sectionone
,sectiontwo
等表是否对每个客户都有一行。
可能的情况是这些。
client
和sectionone
等之间精确的一对一关系。
- 一对零或一关系
- 一对零一对多关系
在您问题的字里行间阅读,在我看来,您认为您有第一种情况,但实际上您有第三种情况。也就是说,您可能有多个sectionthree
特定客户端 ID 的行。
您在结果集中想要的是每个看起来像这样的客户的单行。
clientid one two three four
123 45 55 20 56
像这样的查询清楚地可视化您想要的结果集很重要。但你知道的。
所以,我们开始吧。我们需要sectionX
一一总结表格,因为我们必须创造一种错觉,即每个客户端只有一行,即使他们没有。
SELECT client_id, AVG(percent) AS percent
FROM sectionone
GROUP BY client_id
相同的查询适用于所有四个sectionX
表。我们将使用其中四个汇总查询作为其余主查询的虚拟表。
接下来,我们必须将这四个汇总查询加入到client
表中。我们应该使用 LEFT JOIN 命令来涵盖sectionX
表可能包含特定客户端的零行的情况。
SELECT z.client_id, a.percent AS one, b.percent AS two,
c.percent AS three, d.percent AS four
FROM client as z
LEFT JOIN (
SELECT client_id, AVG(percent) AS percent
FROM sectionone
GROUP BY client_id
) AS a ON z.client_id = a.client_id
LEFT JOIN (
SELECT client_id, AVG(percent) AS percent
FROM sectiontwo
GROUP BY client_id
) AS b ON z.client_id = b.client_id
LEFT JOIN (
SELECT client_id, AVG(percent) AS percent
FROM sectionthree
GROUP BY client_id
) AS c ON z.client_id = c.client_id
LEFT JOIN (
SELECT client_id, AVG(percent) AS percent
FROM sectionfour
GROUP BY client_id
) AS d ON z.client_id = d.client_id
最后,如果你只想要一个 client_id,你应该用
WHERE z.client_id = whatever
如果一个客户的表中有不止一行sectionX
,这种方法会取它们的平均值。如果您需要其他内容,例如 MAX、MIN 等,您可以在查询中使用它。
这看起来很复杂,但实际上很简单,如果您可以将五路表 LEFT JOIN 称为简单 :-)。它适用于本答案开头提到的所有三种情况。
更重要的是,MySQL(和其他 SQL 系统)在优化这种查询方面做得很好,因为它很常见。