我有两张表A和B,如下所示。我想按项目合并它们,但仅限于返回日期在订单日期之后的地方,并且返回日期最接近项目的相应订单日期。结果表格如下。你能帮忙看看我如何在SQL代码中实现这种合并吗?
退货日期不必与订单日期在同一年,但如果返回日期在订单日期之后,则应将其分配到最接近的订单日期。例如,对于项目1,在项目1的三个订单日期中,返回日期9/15/2009最接近8/14/2009,因此它被分配到8/14/2009。同样对于第1项,返回日期9/15/2011是在第1项的所有三个订单日期之后,但它最接近8/16/2011,因此它被分配到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
答案 0 :(得分: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')
答案 1 :(得分: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
答案 2 :(得分: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