数据集之间的SQL Server最佳日期匹配

数据集之间的SQL Server最佳日期匹配,sql,sql-server,tsql,Sql,Sql Server,Tsql,我需要用@thirdParty中的最佳匹配项填充@firstParty 要匹配记录,@firstParty.Registered必须在@thirdParty.Registered的31天内 此外,@thirdParty中的任何记录都不能与@firstParty中的多个记录关联 我希望尽可能高效地完成这项工作。SQL Server版本为2008,因此在此之后引入的功能无法使用 此示例代码是实际代码的简化,我无法发布: declare @firstParty table ( FirstPar

我需要用
@thirdParty
中的最佳匹配项填充
@firstParty

要匹配记录,
@firstParty.Registered
必须在
@thirdParty.Registered
的31天内

此外,
@thirdParty
中的任何记录都不能与
@firstParty
中的多个记录关联

我希望尽可能高效地完成这项工作。SQL Server版本为2008,因此在此之后引入的功能无法使用

此示例代码是实际代码的简化,我无法发布:

declare @firstParty table
(
    FirstPartyId integer identity,
    Registered date,

    MinThirdPartyId integer,
    MinThirdPartyRegistered date

);

insert into @firstParty (Registered)
values
('1/1/2017'), ('2/1/2017'), ('3/1/2017'), ('4/1/2017'), ('5/1/2017'), ('6/1/2017');

/*
dates in @firstParty and @thirdParty are not guaranteed to be unique 
in all scenarios
*/

declare @thirdParty table
(
    ThirdPartyId integer identity,
    Registered date
);

insert into @thirdParty (Registered)
values
('03/02/2017'), ('04/30/2017');


declare @x integer = 1;
while @x <= (select max(FirstPartyId) from @firstParty) begin

    declare @MinRegistered date = null;

    --get minimum third party date within 31 days of registered date, that hasn't been used
    select
        @MinRegistered = min(tp.Registered)     
    from
        @firstParty fp
        join @thirdParty tp on
            fp.Registered between dateadd(d, -31, tp.Registered) and dateadd(d, 31, tp.Registered)
        left join @firstParty used on tp.ThirdPartyId = used.MinThirdPartyId
    where
        fp.FirstPartyId = @x
        and used.MinThirdPartyId is null;

    declare @MinThirdPartyId integer = null;

    --get earliest ID of third party record with @MinRegistered
    select top 1
        @MinThirdPartyId = tp.ThirdPartyId
    from
        @firstParty fp
        join @thirdParty tp on
            tp.Registered = @MinRegistered
        left join @firstParty used on tp.ThirdPartyId = used.MinThirdPartyId
    where
        fp.FirstPartyId = @x
        and used.MinThirdPartyId is null
    order by
        tp.Registered,
        tp.ThirdPartyId;


    update @firstParty
    set
        MinThirdPartyId = @MinThirdPartyId,
        MinThirdPartyRegistered = @MinRegistered
    where
        FirstPartyId = @x;


    set @x = @x + 1;

end;


select
    fp.FirstPartyId,
    fp.Registered,
    fp.MinThirdPartyId,
    fp.MinThirdPartyRegistered
from
    @firstParty fp;

首先填充所有匹配,然后删除非最优匹配的方法将不起作用,因为如果删除@firstParty的最优@thirdParty的记录,@thirdParty中可能有另一个记录仍然是可接受的匹配。

可能是这样的吗

示例

Select A.FirstPartyId
      ,A.Registered
      ,MinThirdPartyId = B.ThirdPartyId
      ,MinThirdPartyRegistered = B.Registered
 From  @firstParty A
 Left  Join (
                Select B1.*
                      ,MinPartyID =B2.FirstPartyID
                 From  @thirdParty B1
                 Cross Apply (
                                Select Top 1 with ties *
                                 From @firstParty
                                 Where abs(DateDiff(DAY,B1.Registered,Registered))<=31
                                 Order By abs(DateDiff(DAY,B1.Registered,Registered)) 
                             ) B2
            ) B
  on (B.MinPartyID=A.FirstPartyId)
选择A.FirstPartyId
,A.注册
,MinThirdPartyId=B.ThirdPartyId
,MinThirdPartyRegistered=B.已注册
来自@甲方
左连接(
选择B1*
,MinPartyID=B2.FirstPartyID
来自第三方B1
交叉应用(
选择带领带的前1名*
来自@firstParty

abs(DateDiff(DAY,B1.Registered,Registered))工作完美。谢谢!@BenOsborne很乐意帮忙
Select A.FirstPartyId
      ,A.Registered
      ,MinThirdPartyId = B.ThirdPartyId
      ,MinThirdPartyRegistered = B.Registered
 From  @firstParty A
 Left  Join (
                Select B1.*
                      ,MinPartyID =B2.FirstPartyID
                 From  @thirdParty B1
                 Cross Apply (
                                Select Top 1 with ties *
                                 From @firstParty
                                 Where abs(DateDiff(DAY,B1.Registered,Registered))<=31
                                 Order By abs(DateDiff(DAY,B1.Registered,Registered)) 
                             ) B2
            ) B
  on (B.MinPartyID=A.FirstPartyId)