SQL 按日期加入和排序个人主题

SQL Joining and ordering invididual subjects by date

所以我有两个SQLtable,一个是客户通讯录,一个是购买日志。

客户Table

Cust ID      Cust Name
1            Adam
2            Brian
3            Charles
4            Dave
...

购买记录

Customer ID         Price          Date
1                   0           1996-01-20
1                   0           1995-01-01
2                               1999-05-22
...

我想看的是客户名称和最近一次购买的价格。 所以 table 应该是这样的:

 Customer Name      Price      
 Adam               0
 Brian              
 ...

我想我对使用哪些函数(如排序依据、限制和连接)有一个大致的了解,但我无法将它们组合在一起。

更糟糕的是,我需要找出处理联系的方法,这意味着如果客户在同一天进行多次购买。默认情况下,我认为它只会列出第一个价格,但我如何才能让它列出当天的最高价格?还是平均价?

让我们暂时搁置您写的领带问题,从基础开始,将名称纳入购买 table。这是一个简单的连接:

SELECT c.name, p.price, p.date from purchase as p inner join customer as c
ON c.cust_id = c.customer_id;

这会给你一个 table 包含所有购买的名称。
现在,您可以在此添加平均值、总和、最大值或任何您想要的聚合,例如:

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;

您可以使用 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 中,如果一天有两个价格,Postgres 将选择最高的价格。

另一种选择是加入派生的 table(这可能更快)

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;

记录排名的标准 SQL 方式是 RANKDENSE_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;