SQL按日期

时间:2017-06-18 19:09:01

标签: sql postgresql join sql-order-by greatest-n-per-group

所以我有两个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)有一个大概的概念,但我无法将它们放在一起。

更糟糕的是,我需要找出处理关系的方法,这意味着如果客户在同一天购买了多个商品。默认情况下,我认为它只会列出第一个价格,但我如何制作它以便列出当天的最高价格?还是平均价格?

3 个答案:

答案 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_RANKROW_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;