Mysql 如何在外部查询和子查询中对同一表进行不同分组
表如下所示:Mysql 如何在外部查询和子查询中对同一表进行不同分组,mysql,Mysql,表如下所示: id | number | provider| datetime | keyword|country| 1 | 1 | Mobitel |2012-11-05| JAM | RS | 2 | 2 | Telekom |2013-04-25| ASTRO| RS | 3 | 1 | Si.Mobil|2013-04-27| DOMACE|
id | number | provider| datetime | keyword|country|
1 | 1 | Mobitel |2012-11-05| JAM | RS |
2 | 2 | Telekom |2013-04-25| ASTRO| RS |
3 | 1 | Si.Mobil|2013-04-27| DOMACE| BA |
4 | 4 | Telenor |2013-04-21| BIP | HR |
5 | 7 | VIP |2013-04-18| WIN | CZ |
6 | 13 | VIP |2014-05-21| DOMACE| RS |
7 | 5 | VIP |2014-06-04| WIN | HU |
我需要在一个查询中汇总按关键字和国家分组的所有数字,并再次汇总按关键字、国家和提供者分组的所有数字
下面是我如何尝试的:
SELECT (SELECT SUM(number),country, keyword
FROM daily_subscriptions
WHERE datetime >= '2016-02-01 23:59:59'
GROUP BY country, keyword )
num_of_all_subs,
SUM(number) as num_of_subs,
country,
keyword,
provider
FROM daily_subscriptions
WHERE datetime >= '2016-02-01 23:59:59'
GROUP BY country, keyword, provider
但此查询引发了一个错误:
#1241-操作数应包含1列
以下是我希望得到的:
id | num_of_all_subs|num_of_subs | provider| datetime | keyword|country|
1 | 19 | 4 | Mobitel |2012-11-05| JAM | RS |
2 | 12 | 5 |Telekom |2013-04-25| ASTRO| RS |
3 | 18 | 1 |Si.Mobil |2013-04-27| DOMACE| BA |
4 | 42 | 21 |Telenor |2013-04-21| BIP | HR |
5 | 76 | 23 |VIP |2013-04-18| WIN | CZ |
6 | 13 | 3 |VIP |2014-05-21| DOMACE| RS |
7 | 53 | 11 |VIP |2014-06-04| WIN | HU |
字段num_of_all_subs
意味着lets say JAM(关键字)和RS(国家/地区)的所有数字之和为19,但per Mobitel(提供者)是num_of_subs
4,因为该国家/地区和关键字还有其他提供者(即使它们未显示在表架构中)
请帮我提取这些数据,因为我被卡住了。您对
num\u of\u all\u subs
(一个数字)的子查询必须只返回一列,下一个问题是返回一行。此外,此子查询将在您分组之前进行评估,而您实际上希望首先分组并获取列num\u of_subs
、country
、关键字
和provider
,然后在第一个结果集中添加另一列num\u of_subs
您可以像刚才所描述的那样执行此操作:首先获取分组子查询(这里称为详细信息
),然后使用从属子查询为该子查询中的每一行获取num\u of_all\u subs
,方法是(再次)查看表,并对具有相同提供者和国家/地区的所有行求和:
SELECT
(SELECT SUM(number)
FROM daily_subscriptions ds
WHERE datetime >= '2016-02-01 23:59:59'
and ds.country = details.country
and ds.keyword = details.keyword
) as num_of_all_subs,
details.*
from
(select
SUM(number) as num_of_subs,
country,
keyword,
provider
FROM daily_subscriptions
WHERE datetime >= '2016-02-01 23:59:59'
GROUP BY country, keyword, provider
) as details;
另一种方法是分别计算这两个组,一个包括提供者
(详细信息
),另一个不包括(所有子项
)。一个将包含num\u的子节点
,一个将包含num\u的子节点
。当这两个查询具有相同的国家
和关键字
时,您可以组合(join
)这两个查询:
SELECT
all_subs.num_of_all_subs,
details.*
from
(select
SUM(number) as num_of_subs,
country,
keyword,
provider
FROM daily_subscriptions
WHERE datetime >= '2016-02-01 23:59:59'
GROUP BY country, keyword, provider
) as details
left join
(SELECT
SUM(number) as num_of_all_subs,
country,
keyword
FROM daily_subscriptions
WHERE datetime >= '2016-02-01 23:59:59'
GROUP BY country, keyword
) as all_subs
on all_subs.keyword = details.keyword and all_subs.country = details.country;
在您的情况下,您可以使用连接
而不是左连接
,因为第一个子查询中的每一行都会在第二个子查询中有一行,尽管通常更安全的方法是保留它
虽然从理论上讲,MySQL可以以相同的方式执行这些查询(对于不太复杂的查询,它实际上会在可能和有用的情况下优化和处理依赖的子查询,如联接),但在当前的MySQL版本中,情况很可能不是这样,第二个选项可能更快。无论如何,对于这两个版本,在(国家/地区、关键字、提供商)
上的复合索引将产生奇迹。在sql server或mysql之间进行选择,但不要两者都是好的,现在显示您的预期输出,我不清楚您是要将总计和小计放在同一行,还是要将它们分开rows@ThomasG现在清楚了吗?