所以我有两个SQL表,一个是客户通讯录,另一个是购买日志。
客户表
Cust ID Cust Name
1 Adam
2 Brian
3 Charles
4 Dave
...
购买历史
Customer ID Price Date
1 $100 1996-01-20
1 $200 1995-01-01
2 $70 1999-05-22
...
我想看到的是客户名称和最近购买的价格。 因此表格应如下所示:
Customer Name Price
Adam $100
Brian $70
...
我认为我对要使用的功能(如order by,limit和join)有一个大概的概念,但我无法将它们放在一起。
更糟糕的是,我需要找出处理关系的方法,这意味着如果客户在同一天购买了多个商品。默认情况下,我认为它只会列出第一个价格,但我如何制作它以便列出当天的最高价格?还是平均价格?
答案 0 :(得分:2)
你可以使用Postgres' distinct on ()
运营商:
SELECT distinct on (c.cust_id) c.cust_name, p.price, p.purchase_date
from customer c
join purchase p ON c.cust_id = c.customer_id
order by c.cust_id, p.date desc, p.price desc;
在price desc
order by
中加入select c.cust_id, c.cust_name, p.price, p.purchase_date
from customer c
join (
select distinct on (customer_id) customer_id, price, purchase_date
from purchase
order by customer_id, purchase_date desc, p.price desc
) p on c.cust_id = p.customer_id;
如果一天有两个价格,则会选择最高价格。
另一种选择是加入派生表(可能更快)
{{1}}
答案 1 :(得分:1)
对记录进行排名的标准SQL方法是DENSE_RANK
或ROW_NUMBER
(都考虑关系)或select
customer.cust_name,
ranked.price
from customer
join
(
select
customer_id,
price,
row_number() over (partition by customer_id order by date desc, price desc) as rnk
from purchase_history
) ranked on ranked.customer_id = customer.cust_id and ranked.rnk = 1;
(不会)。
以下查询占用上一个购买日,如果有多次购买,则会选择价格较高的记录。 (如果有两次采购具有相同的最高价格,其中一条记录是随意挑选的,但这并不重要。)
select
customer.cust_name,
avg(ranked.price)
from customer
join
(
select
customer_id,
price,
rank() over (partition by customer_id order by date desc) as rnk
from purchase_history
) ranked on ranked.customer_id = customer.cust_id and ranked.rnk = 1
group by customer.cust_id, customer.cust_name;
以下查询需要购买最后一天的购买日,并计算这些购买日的平均价格。
{{1}}
答案 2 :(得分:0)
让我们暂时搁置您写的关系问题,从基础开始,将名称输入购买表。这是一个简单的连接:
SELECT c.name, p.price, p.date from purchase as p inner join customer as c
ON c.cust_id = c.customer_id;
这将为您提供一个包含所有购买的表格,其名称为 现在,您可以添加平均值,总和,最大值或任何您想要的聚合,例如:
SELECT name, date, MAX(price) from (
SELECT c.name, p.price, p.date from purchase as p inner join customer as c
ON c.cust_id = c.customer_id
) group by name, date;