1

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

退货日期不必与订单日期在同一年,但鉴于退货日期在订单日期之后,应将其分配到最接近的订单日期。例如,对于项目 1,退货日期 2009 年 9 月 15 日在项目 1 的三个订单日期中最接近 2009 年 8 月 14 日,因此分配到 2009 年 8 月 14 日。同样对于商品 1,退货日期 9/15/2011 是商品 1 的所有三个订单日期之后,但它最接近 8/16/2011,因此它被分配到 8/16/2011。

非常感谢!

表 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
4

3 回答 3

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')
于 2012-08-24T07:48:24.553 回答
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
于 2012-08-23T22:44:21.810 回答
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 
于 2012-08-24T07:47:23.697 回答