查找最接近的到期日期

时间:2018-07-11 05:53:08

标签: sql sql-server

我有一个表,该表的列为ItemCodeItemCountExpiredDate,其中随着物品库存增加而保存了物品的过期日期。我有一个视图,显示我的物品的当前库存,其列为ItemCodeItemStock

表格

ItemCode, ItemCount, ExpiredDate
1001    , 200      , 2010/01/01
1001    , 100      , 2020/02/01
1001    , 200      , 2021/03/01
1002    , 150      , 2020/03/01

查看

ItemCode, ItemStock
1001    , 250
1002    , 40
1003    , 50
1004    , 60

我想要一个根据物品库存返回最接近到期​​日期的查询。

结果

ItemCode, ClosestExpirationDate
1001    , 2020/02/01
1002    , 2020/03/01
1003    , -----
1004    , -----

4 个答案:

答案 0 :(得分:2)

尝试使用日期的绝对差值:

WITH cte AS (
    SELECT t1.ItemCode, t2.ExpiredDate,
        ROW_NUMBER() OVER (PARTITION BY t1.ItemCode
            ORDER BY ABS(DATEDIFF(day, GETDATE(), COALESCE(t2.ExpiredDate, GETDATE())))) rn
    FROM [yourView] t1
    LEFT JOIN [yourTable] t2
        ON t1.ItemCode = t2.ItemCode
)

SELECT ItemCode, ExpiredDate AS ClosestExpirationDate
FROM cte
WHERE rn = 1
ORDER BY ItemCode;

enter image description here

Demo

注意:我假设您想要到期日期,而不管它们是过去还是将来。如果您只希望将来的到期日期,则可以对上述查询进行一些修改。

答案 1 :(得分:0)

不幸的是,我无法为您提供确切的查询,但是我可以告诉您如何解决这个难题:

我现在无法验证,但解决方案是这样的:

;with numberedItems as (
   select ItemCode, ExpirationDate,
   row_number() over(partition by ItemCode order by ExpirationDate) as RowNo
   from Items 
)
select ItemCode, ExpirationDate
from numberedItems
where RowNo = 1

此解决方案的好处是SQL Server仅读取您的表一次,您不必执行两个查询即可获得单个结果集。

希望对您有帮助。

答案 2 :(得分:0)

尝试一下:

样本数据:

declare @tbl1 table (ItemCode int, ItemCount int, ExpiredDate date);
insert into @tbl1 values
(1001, 200, '2010/01/01'),
(1001, 100, '2020/02/01'),
(1001, 200, '2021/03/01'),
(1002, 150, '2020/03/01');

declare @tbl2 table (ItemCode int, ItemStock int);
insert into @tbl2 values
(1001, 250),
(1002, 40),
(1003, 50),
(1004, 60);

T-SQL:

select t2.ItemCode, min(t1.ExpiredDate) ClosestExpirationDate from (
    select ItemCode, ItemCount, ExpiredDate,
           SUM(ItemCount) over (partition by ItemCode order by ExpiredDate) CumSum
    from @tbl1
) t1 right join @tbl2 t2 on t1.ItemCode = t2.ItemCode and t1.CumSum > ItemStock
group by t2.ItemCode

对于12之前的SQL Server版本:

select t2.ItemCode, min(t1.ExpiredDate) ClosestExpirationDate from (
    select t1.ItemCode, t1.ItemCount, t1.ExpiredDate, SUM(t2.ItemCount) CumSum 
    from @tbl1 t1
    join @tbl1 t2 on t1.ItemCode = t2.ItemCode and t1.ExpiredDate >= t2.ExpiredDate
    group by t1.ItemCode, t1.ItemCount, t1.ExpiredDate
) t1 right join @tbl2 t2 on t1.ItemCode = t2.ItemCode and t1.CumSum > ItemStock
group by t2.ItemCode

答案 3 :(得分:0)

使用outer apply。我想您希望将来的下一个日期

select v.*, t.ExpiredDate
from view v outer apply
     (select top (1) t.*
      from table t
      where t.ExpiredDate > getdate()
      order by t.ExpiredDate desc
     ) t;

如果您还想包括过去的日期,则其结构非常相似:

select v.*, t.ExpiredDate
from view v outer apply
     (select top (1) t.*
      from table t
      order by datediff(day, getdate(), t.ExpiredDate) asc
     ) t;