2012-08-23 48 views
1

我有两个表A和B,如下所示。我希望按项目进行合并,但仅限于退货日期在订单日期之后且退货日期与该项目的相应订单日期最接近的地方。结果表格如下C所示。你能帮我看看如何在SQL代码中实现这种合并吗?如何合并两个日期最近的两个表?

退货日期不必与订单日期在同一年,但它应该被分配到最近的订单日期,因为退货日期在订单日期之后。例如,对于第1项,9/15/2009的返回日期与第1项的三个订单日期中最接近8/14/2009,因此它被分配到2009年8月14日。对于第1项,2011年9月15日的返回日期是第1项的三个订单日期之后,但最接近于2011年8月16日,因此将其分配给2011年8月16日。

非常感谢!

表A:

Items Order_Date 
1  8/14/2009 
1  8/15/2010 
1  8/16/2011 
2  9/10/2009 
2  9/8/2010 
2  9/12/2011 

表B:

Items Return_Date 
1  9/15/2009 
1  9/15/2011 
2  10/15/2010 
2  11/15/2011 

决赛成绩表C:

Items  Order_Date Return_Date 
1   8/14/2009  9/15/2009 
1   8/15/2010  NULL 
1   8/16/2011  9/15/2011 
2   9/10/2009  NULL 
2   9/8/2010  10/15/2010 
2   9/12/2011  11/15/2011 

回答

1

我用一个APPLY这里也。这似乎符合您的样本数据:

(在回答结束的样本数据)

;with MatchedOrders as (
    select 
     a.Items,a.Order_Date, b.Return_Date 
    from 
     @TableB b 
      cross apply 
     (select top 1 * from @TableA a 
      where a.Items = b.Items and a.Order_Date < b.Return_Date 
      order by a.Order_Date desc) a 
) 
select 
    a.Items, 
    a.Order_Date, 
    mo.Return_Date 
from 
    @TableA a 
     left join 
    MatchedOrders mo 
     on 
      a.Items = mo.Items and a.Order_Date = mo.Order_Date 

结果:

Items  Order_Date     Return_Date 
----------- --------------------------- --------------------------- 
1   2009-08-14 00:00:00.0000000 2009-09-15 00:00:00.0000000 
1   2010-08-15 00:00:00.0000000 NULL 
1   2011-08-16 00:00:00.0000000 2011-09-15 00:00:00.0000000 
2   2009-09-10 00:00:00.0000000 NULL 
2   2010-09-08 00:00:00.0000000 2010-10-15 00:00:00.0000000 
2   2011-09-12 00:00:00.0000000 2011-11-15 00:00:00.0000000 

的样本数据:

declare @TableA table (Items int not null,Order_Date datetime2 not null) 
insert into @TableA(Items,Order_Date) values 
(1,'20090814'), 
(1,'20100815'), 
(1,'20110816'), 
(2,'20090910'), 
(2,'20100908'), 
(2,'20110912') 

declare @TableB table (Items int not null,Return_Date datetime2 not null) 
insert into @TableB(Items,Return_Date) values 
(1,'20090915'), 
(1,'20110915'), 
(2,'20101015'), 
(2,'20111115') 
0

我觉得OUTER APPLY是你所需要的。您是否尝试过这样的事情(SQLServer的):

Select A.ItemID, A.OrderDate, [ReturnDates].ReturnDate 
from Orders A 
    OUTER APPLY (
     select Min(ReturnDate) as ReturnDate 
     From [Returns] b 
     where b.ReturnDate >= A.OrderDate AND b.ItemID = A.ItemID 
     ) as ReturnDates 
+0

感谢RyanD ,但结果与我在那里发布的结果不一样e“NULL”。 – Wayne

+0

PSN \t \t ORDER_DATE opt_out_date \t 2009年8月14日9/15/2009 \t 2010年8月15日2011/9/15 \t 2011/8/16 2011/9/15 - About SOHU \t 10/15/2010 2010/9/8 \t 10/15/2010 2011年9月12日\t 11/15/2011 – Wayne

+1

林,我怎么没看到你根据您解释的标准从表C中获得结果。也许你需要澄清。回报日期应该是在同一年吗? – Jim

0

试试这个:

select ord.Items,ord.Order_Date,l.Return_Date from orders ord 
left join 
(
select * from (
select *,row_number() over (partition by return_date order by diff asc) as rn from (

select b.Items,b.Order_Date,a.Return_Date,a.diff from 

(select o.Items,o.Order_Date,r.Return_Date,DATEDIFF(dd,o.Order_Date,r.Return_Date) diff from orders o join ord_ret r 
on o.Items = r.Items) a inner join 

(select a.Items,a.Order_Date,MIN(abs(a.diff)) as diff 
from (
select o.Items,o.Order_Date,r.Return_Date,DATEDIFF(dd,o.Order_Date,r.Return_Date) diff from orders o join ord_ret r 
on o.Items = r.Items) a 
group by a.Items,a.Order_Date) b 

on a.Items = b.Items and a.diff = b.diff and a.Return_Date > b.Order_Date) a) final 
where rn<> 2) l 

on ord.Items = l.Items and ord.Order_Date = l.Order_Date