Sql 如果分发日期和装运日期是唯一的,则不需要 或 ( dtExists.dayDiff=距离.dayDiff 和 ( dtExists.Pro_Row_ID

Sql 如果分发日期和装运日期是唯一的,则不需要 或 ( dtExists.dayDiff=距离.dayDiff 和 ( dtExists.Pro_Row_ID,sql,sql-server,Sql,Sql Server,如果分发日期和装运日期是唯一的,则不需要 或 ( dtExists.dayDiff=距离.dayDiff 和 ( dtExists.Pro_Row_ID

如果分发日期和装运日期是唯一的,则不需要 或 ( dtExists.dayDiff=距离.dayDiff 和 ( dtExists.Pro_Row_ID您使用的是MySQL还是MS SQL Server?(这些产品以不同的方式处理日期/时间。)您试过了吗?为什么最近的装运日期是2016年11月28日、2016年11月19日,而不是11月21日或11月28日?在“分发日期”和“装运日期”之间允许的最大差值(以天为单位)是多少。简而言之,“最近发货日期”的最大值是多少?嗨,我使用的是ms SQL Server。非常感谢Woodan。你救了我三天。我感谢你的努力。
ID       Dispense date  Row ID
604743   10/18/2016     1
604743   11/4/2016      2
604743   11/28/2016     3
604743   12/16/2016     4
ID       Shipment Date  Row ID
604743   11/1/2016      1
604743   11/19/2016     2
604743   11/21/2016     3
604743   11/28/2016     4
604743   12/13/2016     5
ID       Dispense date  Pre Ship date
604743   10/18/2016     NULL 
604743   11/4/2016      11/1/2016
604743   11/28/2016     11/19/2016
604743   12/16/2016     12/13/2016
--- Dispense_Date must not be unique
declare @Dispense table(
    ID int not null,
    Dispense_Date date not null,
    Row_ID int not null identity primary key
)
-- Shipment_Date must not be unique
declare @Pro table(
    ID int not null,
    Shipment_Date date not null,
    Row_ID int not null identity primary key
)
declare @Result table(
    ID int not null,
    Dispense_Date date not null,
    Dispense_Row_ID int not null unique,
    Shipment_Date date not null,
    Pro_Row_ID int not null unique,
    dayDiff int not null,
    Row_ID int not null identity primary key,
    iter int not null
)

insert into @Dispense(ID, Dispense_Date)
values  (604743, '10/18/2016'),
        (604743, '11/4/2016'),
        /* (604743, '11/26/2016'),
        (604743, '11/27/2016'),
        (604743, '11/27/2016'),
        (604743, '11/28/2016'), */
        (604743, '11/28/2016'),
        (604743, '12/16/2016')

insert into @Pro(ID, Shipment_Date)
values  (604743, '11/1/2016'),
        /* (604743, '11/16/2016'),
        (604743, '11/19/2016'), */
        (604743, '11/19/2016'),
        (604743, '11/21/2016'),
        (604743, '11/28/2016'),
        (604743, '12/13/2016')

declare @iter int = 0

while exists(
    select      1
    from        @Dispense Dispense
                inner join
                @Pro Pro
                on  Pro.ID = Dispense.ID
                    and
                    Pro.Shipment_Date < Dispense.Dispense_Date
    where       not exists(
                    select      1
                    from        @Result Result
                    where       Result.Dispense_Row_ID = Dispense.Row_ID
                                or
                                Result.Pro_Row_ID = Pro.Row_ID
                )
)
begin
    set @iter = @iter + 1
    ;   
    with distance(
        ID, Dispense_Row_ID, Dispense_Date, Pro_Row_ID, Shipment_Date, dayDiff
    ) as(
        select      Dispense.ID,
                    Dispense.Row_ID Dispense_Row_ID,
                    Dispense.Dispense_Date,
                    Pro.Row_ID Pro_Row_ID,
                    Pro.Shipment_Date,
                    DATEDIFF(DAY, Pro.Shipment_Date, Dispense.Dispense_Date) dayDiff
        from        @Dispense Dispense
                    inner join
                    @Pro Pro
                    on  Pro.ID = Dispense.ID
                        and
                        Pro.Shipment_Date < Dispense.Dispense_Date
        where       not exists(
                        select      1
                        from        @Result Result
                        where       Result.Dispense_Row_ID = Dispense.Row_ID
                                    or
                                    Result.Pro_Row_ID = Pro.Row_ID
                    )

    )

    insert into @Result(ID, Dispense_Row_ID, Dispense_Date, Pro_Row_ID, Shipment_Date, daydiff, iter)
    select      Dispense.ID,
                Dispense.Row_ID Dispense_Row_ID,
                Dispense.Dispense_Date,
                distance.Pro_Row_ID,
                distance.Shipment_Date,
                distance.dayDiff,
                @iter
    from        @Dispense Dispense
                inner join
                distance
                on  distance.Dispense_Row_ID = Dispense.Row_ID
                    and
                    not exists(
                        select      1
                        from        distance dtExists
                        where       dtExists.ID = distance.ID
                                    and
                                    dtExists.Shipment_Date = distance.Shipment_Date
                                    and
                                    (
                                        dtExists.dayDiff < distance.dayDiff
                                        -- below OR not needed if Dispense_Date and Shipment_Date are unique
                                        or
                                        (
                                            dtExists.dayDiff = distance.dayDiff
                                            and
                                            (
                                                dtExists.Pro_Row_ID < distance.Pro_Row_ID
                                                or
                                                (
                                                    dtExists.Pro_Row_ID = distance.Pro_Row_ID
                                                    and
                                                    dtExists.Dispense_Row_ID < distance.Dispense_Row_ID
                                                )
                                            )
                                        )
                                    )
                    )
                    and
                    not exists(
                        select      1
                        from        distance dtExists
                        where       dtExists.ID = distance.ID
                                    and
                                    dtExists.Dispense_Date = distance.Dispense_Date
                                    and
                                    (
                                        dtExists.dayDiff < distance.dayDiff
                                        -- below OR not needed if Dispense_Date and Shipment_Date are unique
                                        or
                                        (
                                            dtExists.dayDiff = distance.dayDiff
                                            and
                                            (
                                                dtExists.Pro_Row_ID < distance.Pro_Row_ID
                                                or
                                                (
                                                    dtExists.Pro_Row_ID = distance.Pro_Row_ID
                                                    and
                                                    dtExists.Dispense_Row_ID < distance.Dispense_Row_ID
                                                )
                                            )
                                        )
                                    )
                    )
end

select      Dispense.ID,
            Dispense.Row_ID Dispense_Row_ID,
            Dispense.Dispense_Date,
            Result.Pro_Row_ID,
            Result.Shipment_Date,
            Result.dayDiff,
            Result.iter
from        @Dispense Dispense
            left join
            @Result Result
            on  Result.Dispense_Row_ID = Dispense.Row_ID
order by    Dispense.ID,
            Dispense.Dispense_Date,
            Result.Shipment_Date,
            Result.Dispense_Row_ID,
            Result.Pro_Row_ID