我有一个查询应该返回每个客户最热门产品类型的客户列表。我有一个查询,总结了在所有给定产品类型中购买的每个产品,并按每个客户的降序列出
SELECT c.customer_name as cname, ptr.product_type as pop_gen, sum(od.quantity) as li
FROM product_type_ref as ptr
INNER JOIN product as p
on p.product_type_ref_id = ptr.product_type_ref_id
INNER JOIN order_detail as od
on od.product_id = p.product_id
INNER JOIN order as o
on o.order_id = od.order_id
INNER JOIN customer as c
on c.customer_id = o.customer_id
GROUP BY cname, pop_gen
ORDER BY cname, li DESC
返回此数据:
'andy','Drama',1000
'andy','Action',250
'andy','Comedy',100
'bebe','Drama',250
'bebe','Action',100
'bebe','Comedy',25
'buster','Action',825
'buster','Comedy',768
'buster','Drama',721
'buster','Romance',100
'ron','Romance',50
'ron','Comedy',10
我怎么能回复这个:
andy, Drama
bebe, Drama
buster, Action
ron, Romance
答案 0 :(得分:1)
在Postgres中,您可以使用distinct on
:
SELECT DISTINCT ON (c.customer_name) c.customer_name as cname,
ptr.product_type as pop_gen, sum(od.quantity) as li
FROM product_type_ref as ptr
INNER JOIN product as p
on p.product_type_ref_id = ptr.product_type_ref_id
INNER JOIN order_detail as od
on od.product_id = p.product_id
INNER JOIN order as o
on o.order_id = od.order_id
INNER JOIN customer as c
on c.customer_id = o.customer_id
GROUP BY cname, pop_gen
ORDER BY cname, li DESC;
答案 1 :(得分:0)
添加ROW_NUMBER()
SELECT *
FROM (
SELECT c.customer_name as cname,
ptr.product_type as pop_gen,
sum(od.quantity) as li,
ROW_NUMBER() OVER (PARTITION BY c.customer_name
ORDER BY sum(od.quantity) DESC) as rn
......
) as T
WHERE T.rn = 1
答案 2 :(得分:0)
经典greatest-n-per-group
。一种可能的解决方案是使用ROW_NUMBER()
:
WITH
CTE
AS
(
SELECT
c.customer_name as cname, ptr.product_type as pop_gen, sum(od.quantity) as li
,ROW_NUMBER() OVER(PARTITION BY c.customer_name ORDER BY sum(od.quantity) DESC) AS rn
FROM
product_type_ref as ptr
INNER JOIN product as p on p.product_type_ref_id = ptr.product_type_ref_id
INNER JOIN order_detail as od on od.product_id = p.product_id
INNER JOIN order as o on o.order_id = od.order_id
INNER JOIN customer as c on c.customer_id = o.customer_id
GROUP BY
cname, pop_gen
)
SELECT
cname, pop_gen, li
FROM CTE
WHERE rn = 1
ORDER BY cname;