SQL 查询,特定字段上的一条记录,带有 group by 子句

Posted

技术标签:

【中文标题】SQL 查询,特定字段上的一条记录,带有 group by 子句【英文标题】:SQL query, one record on a particular field with a group by clause 【发布时间】:2021-01-23 23:08:27 【问题描述】:

我不知道这是否可能。如果没有,没关系。当然还有其他方法可以做到这一点。一位同事告诉我,这是不可能的,我们在此基础上喝了一轮酒。不,我不介意寻求帮助,但我想我会购买。

问题是:给我一份报告,按最大单笔订单列出每个国家/地区的***客户。目标是在不使用子查询、窗口函数或普通连接以外的任何东西的情况下回答问题。

到目前为止,这是我的查询。它在 SQLite 中,并不重要。

select o.customerid, c.companyname, c.country,
od.quantity * od.unitprice as total_order
from orders o
join order_details od on o.orderid = od.orderid
join customers c on o.customerid = c.customerid
group by  c.country
order by c.country, total_order desc;

这是结果。

CustomerID,CompanyName,Country,total_order
OCEAN,"Océano Atlántico Ltda.",Argentina,223.2
ERNSH,"Ernst Handel",Austria,760.0
SUPRD,"Suprêmes délices",Belgium,2592.0
HANAR,"Hanari Carnes",Brazil,77.0
MEREP,"Mère Paillarde",Canada,2000.0
SIMOB,"Simons bistro",Denmark,16.0
WARTH,"Wartian Herkku",Finland,364.8
VINET,"Vins et alcools Chevalier",France,168.0
TOMSP,"Toms Spezialitäten",Germany,167.4
HUNGO,"Hungry Owl All-Night Grocers",Ireland,608.0
MAGAA,"Magazzini Alimentari Riuniti",Italy,43.2
CENTC,"Centro comercial Moctezuma",Mexico,80.0
SANTG,"Santé Gourmet",Norway,54.0
WOLZA,"Wolski  Zajazd",Poland,300.0
FURIB,"Furia Bacalhau e Frutos do Mar",Portugal,396.0
ROMEY,"Romero y tomillo",Spain,7.3
FOLKO,"Folk och fä HB",Sweden,532.0
CHOPS,"Chop-suey Chinese",Switzerland,54.0
BSBEV,"B''s Beverages",UK,240.0
RATTC,"Rattlesnake Canyon Grocery",USA,204.0
HILAA,HILARION-Abastos,Venezuela,877.5

这是一个测试查询,看起来是阿根廷。

select o.orderid, o.customerid, c.companyname, c.country,
od.quantity * od.unitprice as total_order
from orders o
join order_details od on o.orderid = od.orderid
join customers c on o.customerid = c.customerid
where c.country like "Argentina"
group by  c.country, o.orderid
order by c.country, total_order desc;

这是测试查询的结果。

OrderID,CustomerID,CompanyName,Country,total_order
10986,OCEAN,"Océano Atlántico Ltda.",Argentina,630.0
10958,OCEAN,"Océano Atlántico Ltda.",Argentina,427.0
10828,RANCH,"Rancho grande",Argentina,405.0
10937,CACTU,"Cactus Comidas para llevar",Argentina,364.8
10819,CACTU,"Cactus Comidas para llevar",Argentina,322.0
10409,OCEAN,"Océano Atlántico Ltda.",Argentina,223.2
10881,CACTU,"Cactus Comidas para llevar",Argentina,150.0
10448,RANCH,"Rancho grande",Argentina,149.4
10531,OCEAN,"Océano Atlántico Ltda.",Argentina,110.0
10916,RANCH,"Rancho grande",Argentina,104.7
10521,CACTU,"Cactus Comidas para llevar",Argentina,54.0
10716,RANCH,"Rancho grande",Argentina,50.0
11019,RANCH,"Rancho grande",Argentina,36.0
10898,OCEAN,"Océano Atlántico Ltda.",Argentina,30.0
11054,CACTU,"Cactus Comidas para llevar",Argentina,25.0
10782,CACTU,"Cactus Comidas para llevar",Argentina,12.5

显然,阿根廷最大的客户是 Océano Atlántico Ltda。订单为 630.00,但第一个结果显示为订单 223.2。是的,我可以使用窗口函数或子查询,但挑战在于仅使用表连接。这可能吗?谢谢。

【问题讨论】:

【参考方案1】:

如果您必须从订单行汇总订单大小,那么我认为这是不可能的。以下不是证明。这是对我的想法的解释。

如果您在订单表中有可用的订单大小,那么应该是可以的。

该查询的基本结构是:

select o.*, c.country
from orders o join
     customers c
     on o.customerid = c.customerid left join
     (orders o2 join
      customers c2
      on o2.customerid = c2.customerid
     )
     on c2.country = c.country and
        o2.ordersize > o.ordersize
where c2.country is null;  -- no bigger order in the country

但是,在您的问题中,您需要从另一个表中汇总订单大小。这就是问题所在,因为您需要 ON 子句中的总订单大小,因此聚合必须出现在连接“之前”。我想不出不使用子查询或 CTE 的方法。

还有其他方法可以获得最大订单,但排除窗口函数和子查询几乎可以排除它们。这并不是说不可能,只是由于聚合问题,我无法轻易想到解决方案。

【讨论】:

以上是关于SQL 查询,特定字段上的一条记录,带有 group by 子句的主要内容,如果未能解决你的问题,请参考以下文章

SQL某一表中重复某一字段重复记录查询与处理

oracle中把查询到的一条记录的某个字段赋值给一个变量

求sql语句,只修改重复数据中的一条记录

在访问查询中仅显示具有特定字段数据的最后一条记录

多表查询结果出现重复记录,根据条件只取其中的一条记录的sql语句

sql 根据字段取最小的一条值