SQL Server:从连接查询中仅选择每个客户的最后一条记录

时间:2016-12-29 12:12:41

标签: sql sql-server

假设我有这3个表:

Customer type 1

Customer type 2

enter image description here

前两个表定义了不同类型的客户,即第二个表有其他列未包含在表1中我只是将它们保持相同以节省复杂性。

第三个表定义了两种类型客户的订单。每个客户都有多个订单

我想为每位客户选择最后一个订单,即2016年12月23日创建的order_id 1 customer 4订单和order_id订单5 for customer 2于2016年12月26日创建

我试过这样的事情:

select * 
from customertype1 
left join order on order.customer_id = customertype1.customer_id 
order by order_id desc;

但这给了我每个客户的多条记录,正如我上面所说,我只想要每个customertype1的最后一个订单。

3 个答案:

答案 0 :(得分:3)

如果您想要每个客户的最后一个订单,那么您只需要orders表:

select o.*
from (select o.*,
             row_number() over (partition by customer_id order by datecreated desc) as seqnum
      from orders o
     ) o
where seqnum = 1;

如果要包含所有客户,则需要合并这两个表。假设它们是互斥的:

with c as (
      select customer_id from customers1 union all
      select customer_id from customers2
     )
select o.*
from c left join
     (select o.*,
             row_number() over (partition by customer_id order by datecreated desc) as seqnum
      from orders o
     ) o
     on c.customer_id = o.customer_id and seqnum = 1;

关于您的数据结构的说明:您应该为所有客户提供一个表。然后,您可以在orderscustomers之间定义外键约束。对于其他列,您可以为不同类型的客户提供其他表。

答案 1 :(得分:0)

使用ROW_NUMBER()PARTITION BY

  • ROW_NUMBER():它会为每一行提供序列号
  • PARTITION BY:它会按给定列
  • 对数据进行分组

当您同时使用ROW_NUMBER()PARTITION BY时,首先按分组对您的记录进行分组,然后row_number为每个组提供序列号no,因此对于每个组,您的起始序列为1

帮助链接:Example of ROW_NUMBER() and PARTITION BY

答案 2 :(得分:0)

这是一般的想法。你可以弄清楚细节。

with customers as
(select customer_id, customer_name
from table1
union
select customer_id, customer_name
from table2)

, lastOrder as
(select customer_id, max(order_id) maxOrderId
 from orders
 group by customer_id)

select *
from lastOrder join customers on lastOrder.Customer_id = customers.customer_id
 join orders on order_id = maxOrderId