SQL 查询 - 如何使用 group by 获取 2 行或更多行
Posted
技术标签:
【中文标题】SQL 查询 - 如何使用 group by 获取 2 行或更多行【英文标题】:SQL query - how to get 2 or more rows with group by 【发布时间】:2017-02-15 23:40:18 【问题描述】:我有两张桌子。一个是带有列的客户表:cid、name、state。 另一个表是 Purchase 表,列有:pid、cid、booktitle、price。
客户:
CID NAME STATE
1 Peng NY
2 Li IL
3 Chan NY
购买:
PID CID BOOKTITLE PRICE
10 1 ABC 20
11 3 XYZ 15
12 1 MNOP 12
输出:
STATE CID NAME
NY 1 Peng
IL null null
我需要输出每个州购买量最高(最大订单)的客户的 cid 和名称。我可以为每个客户输出 cid、姓名、状态和购买次数,但不能为每个状态获取它,因为在使用 group by 函数时我不能使用更多列:
select c.cid, c.name, c.state, d.orders
from customer c
left join (select cid, count(pid) as orders
from purchase
group by cid) d
on c.cid = d.cid;
谁能建议我应该如何进行?
【问题讨论】:
您在谈论“最大订单”,但在 ORDERS 表中您只有一个 PRICE 列。你的意思是“最高价格”吗?另外,如果在一个州有两个或多个客户以最高价格捆绑,您希望退回什么?将它们都(全部)归还?或者只是其中一个,随机的? 没有。不是价格。我的意思是最大订单数。意思是,客户完成的最大购买量。 对于第二部分,如果出现平局,随机客户或两者(全部)都有效。任何输出都是可以接受的。谢谢 您的问题不清楚。根据您上面的措辞,您需要按州分组的 cid 和客户名称,但您已经拥有 cid、客户名称、州和订单数量。请更具体地说明您的问题,并提供您预期输出的示例表。 @EdwardRusu 对不起,我是新手。我没有订单数量。我只有一个名为 purchase 的表,它记录了各个客户下的单个订单。我已经给出了上面的输出表。也许你没看到。请告诉我还有什么需要澄清的。 【参考方案1】:您可以将窗口函数与聚合函数结合起来:
select cp.*
from (select c.cid, c.name, c.state, count(p.cid) as orders,
row_number() over (partition by c.state order by count(p.cid) desc) as seqnum
from customer c left join
purchase p
on c.cid = p.cid
group by c.cid, c.name, c.state
) cp
where seqnum = 1;
您要查找的值称为mode
。如果您想要给定状态的所有模式,请使用 rank()
或 dense_rank()
而不是 row_number()
。
【讨论】:
连接应该在 c.cid = p.cid;无论如何,这不会将 IL 作为结果的一部分。 @gregory 。 . .我认为只需要left join
而不是join
。【参考方案2】:
with cnt as (
select c.state, c.name, c.cid, count(p.cid) orders from customer c
left outer join purchase p on p.cid = c.cid
group by c.state, c.name, c.cid )
select state,
case when orders=0 then null else cid end cid,
case when orders=0 then null else name end name
from (select state, name, cid, orders,
row_number() over (partition by state order by orders desc) rn
from cnt)
order by name, state;
结果:
STATE CID NAME
---------- ---------- ----------
NY 1 Peng
IL
【讨论】:
谢谢。这就是我一直在寻找的。我没有意识到我可以用分析函数解决这个问题。【参考方案3】:WITH
orders AS
( -- enumerate the values by buckets of state
-- ordered by num_orders per state
SELECT
ROW_NUMBER() OVER (PARTITION BY state ORDER BY num_orders DESC) rn
, state
, cid
, num_orders
FROM
( -- calculate counts by state and customer id
SELECT
c.state
, p.cid
, COUNT(p.pid) as num_orders
FROM purchase p
INNER JOIN customer c ON p.cid = c.cid
GROUP BY
c.state
, p.cid
)
)
-- return desired values
SELECT
c.state
, c.cid
c.name
FROM customer c
LEFT JOIN orders o
ON
c.cid = o.cid
AND c.state = o.state
AND rn = 1
【讨论】:
以上是关于SQL 查询 - 如何使用 group by 获取 2 行或更多行的主要内容,如果未能解决你的问题,请参考以下文章
如何在linq C#中使用group by并获取记录列表[重复]
mysql在group by之后如何获取每一组中id最大的那一行
如何在 laravel 中使用 concat 和 group by?