为聚合连接多个表

Jan*_*ani 4 mysql join aggregate count sum

如何使用 Sum 和 Count 函数连接多个表进行聚合?

我正在尝试的查询如下:

Select
  campaigns.id,
  campaigns.name,
  Count(landers.campaign_id) As landers_count,
  Sum(conversions.revenue) As total_revenue
From
  campaigns Left Join
  conversions
    On campaigns.id = conversions.campaign_id Left Join
  landers
    On campaigns.id = landers.campaign_id
Group By
  campaigns.id
Run Code Online (Sandbox Code Playgroud)

我什至尝试过外部连接,但没有运气,而且我得到的结果不准确。

我的示例表如下:

活动表:

| id | name           |
+----+----------------+
| 1  | Facebook Ads   |
| 2  | Bing Ads       |
| 3  | Direct Mailing |
| 4  | Solo Ads       |
Run Code Online (Sandbox Code Playgroud)

兰德斯表:

| id | name        | campaign_id |
+----+-------------+-------------+
| 1  | Lander 1    | 1           |
| 2  | Lander Two  | 2           |
| 3  | Lander 3    | 4           |
| 4  | Lander Four | 1           |
Run Code Online (Sandbox Code Playgroud)

转换表:

| id | revenue | campaign_id | lander_id |
+----+---------+-------------+-----------+
| 1  | 25.00   | 1           | 1         |
| 2  | 12.00   | 1           | 4         |
| 3  | 19.00   | 4           | 3         |
Run Code Online (Sandbox Code Playgroud)

我期待的结果应该如下所示:

| campaigns.id | campaigns.name | landers_count | total_revenue |
+--------------+----------------+---------------+---------------+
| 1            | Facebook Ads   | 2             | 37.00         |
| 2            | Bing Ads       | 1             | 00.00         |
| 3            | Direct Mailing | 0             | 00.00         |
| 4            | Solo Ads       | 1             | 19.00         |
Run Code Online (Sandbox Code Playgroud)

小提琴基于@'Willem Renzema' 的回答

小提琴

Tho*_*ner 5

这个请求已经很老了,但由于接受的答案是错误的,我想我会添加一个正确的答案,这样未来的读者就不要太困惑了。

一个campain有着陆器和转换。如果我们仅仅连接所有表,我们会得到一个包含两个着陆器和三个转换 2 x 3 = 6 结果行的活动。如果我们求和或计数,我们会得到错误的结果(在示例中着陆器的数量将是三倍,转换和将加倍)。

主要有两种方法可以解决这个问题:

在 select 子句中的子查询中聚合。

select
  id, name,
  (select count(*) from landers l where l.campaign_id = ca.id) as landers_count,
  (select sum(revenue) from conversions co where co.campaign_id = ca.id) as total_revenue
from campaigns ca
order by id;
Run Code Online (Sandbox Code Playgroud)

加入前聚合。

select ca.id, ca.name, l.landers_count, co.total_revenue
from campaigns ca
left join
(
  select campaign_id, count(*) as landers_count
  from landers
  group by campaign_id
) l on l.campaign_id = ca.id
left join
(
  select campaign_id, sum(revenue) as total_revenue
  from conversions
  group by campaign_id
) co on co.campaign_id = ca.id
order by ca.id;
Run Code Online (Sandbox Code Playgroud)

您可以使用COALESCE获取结果中的零而不是空值。


Wil*_*ema 0

该答案不正确,但我无法删除已接受的答案。

相反,请参阅此问题的其他答案以获取解决方案。