写一个查询,确定每个国家在音乐上花费最多的客户。编写一个查询,返回该国家和最大客户以及他们花费了多少。对于共享最高消费金额的国家/地区,请提供所有使用此金额的客户。
您只需要使用“客户”和“发票”表。
我想选择在每个国家/地区花费最多的顾客,并且有两个顾客在同一国家/地区花费相同的金钱,所以当按组使用时,我只有1个顾客,我应该怎么做?
select c.CustomerId,c.FirstName,c.LastName, c.Country , max(c.Invoices) as TotalSpent
from
(select * , sum(i.Total) as 'Invoices'
from Customer d
join Invoice i on i.CustomerId = d.CustomerId
group by i.CustomerId
) c
group by c.Country
我得到的表与1位顾客相同,是期望的表
答案 0 :(得分:0)
您的内部查询几乎是正确的。应该是
select d.*, sum(i.Total) as Invoices
from Customer d
join Invoice i on i.CustomerId = d.CustomerId
group by d.CustomerId
这里可以使用d.*
,因为我们可以假设d.CustomerId
是表的主键,因此表中的所有列在功能上都依赖于它。例如,如果我们按d.country
分组,则不是这种情况,并且select子句(以及d.*
等中将禁止d.firstname
)。我们只能选择(直接或间接)分组的列以及MIN
,MAX
,SUM
等聚合。
此查询为您提供每个客户以及客户所在国家/地区的总数。
但是,您将获得此结果并按country
分组。如果执行此操作,则只能访问country
及其集合。例如,选择c.CustomerId
是无效的,因为每个国家/地区没有 客户ID。如果您的DBMS允许这样做,则在这方面有缺陷,您会得到某种随机结果。
如果您的DBMS具有窗口功能,则可以即时获取每个国家/地区的最高金额:
select customerid, firstname, lastname, country, invoices
from
(
select
c.*,
sum(i.total) as invoices,
max(sum(i.total)) over (partition by c.country) as max_sum
from customer c
join invoice i on i.customerid = c.customerid
group by c.customerid
) per_customer
where invoices = max_sum
order by country, customerid;
否则,您将必须使用两次内部查询,一次是获取国家/地区总计,一次是使与这些总计相匹配的客户:
select
c.customerid, c.firstname, c.lastname, c.country,
sum(i.total) as invoices
from customer c
join invoice i on i.customerid = c.customerid
group by c.customerid
having (c.country, invoices) in
(
select country, max(invoices)
from
(
select
--c.customerid, <- optional, it may make this query more readable
c.country,
sum(i.total) as invoices
from customer c
join invoice i on i.customerid = c.customerid
group by c.customerid
) per_customer
);
答案 1 :(得分:0)
考虑通过两个汇总查询加入单位级别:1)首先通过 CustomerId 和 Country 计算总金额,然后2)通过计算最大总金额国家。
以下假设您的数据库使用WITH
子句(几乎所有主要的商业或开源RDBMS都支持)支持公用表表达式(CTE)。此处的CTE避免了将 sum_agg 作为子查询重复的需求。
with sum_agg AS (
select i.CustomerId, sub_c.Country, sum(i.Total) as Sum_Amount
from Customer sub_c
join Invoice i on i.CustomerId = sub_c.CustomerId
group by i.CustomerId, sub_c.Country
)
select c.CustomerId, c.FirstName, c.LastName, c.Country, max_agg.Max_Sum
from Customer c
join sum_agg
on c.CustomerId = sum_agg.Customer_Id and c.Country = sum_agg.Country
join
(select Country, max(Sum_Amount) as Max_Sum
from sum_agg
group by Country
) max_agg
on max_agg.Country = sum_agg.Country and max_agg.Max_Sum = sum_agg.Sum_Amount