【问题标题】:Find overlapping price validity dates in SQL在 SQL 中查找重叠的价格有效日期
【发布时间】:2017-05-04 18:09:50
【问题描述】:

我面临的挑战是我有限的 SQL 技能无法掌握的。我希望你能帮助我。鉴于我有一张表,其中包含在指定时间跨度内对特殊客户有效的商品价格。

因为人们有时只是在输入时间跨度的新价格之前没有思考,我必须找出项目编号和客户编号组合的时间跨度重叠的地方。我只需要找出是否存在重叠发生,而不是重叠发生时。

我有一张 CustomerPrices 表格,里面有这样的数据:

Item No   Customer No     Valid from    Valid to      Price
12345     55544           01.01.2016    31.05.2016    5,66
12345     55544           01.03.2017    01.06.2017    4,55
12345     55544           01.02.2017    01.07.2017    6,41

你能指出我正确的方向吗?

最好的问候,谢谢!

【问题讨论】:

  • 你的 dbms 是什么?
  • 我正在使用 SSMSE!

标签: sql sql-server date overlap timespan


【解决方案1】:

如果您只需要重叠的客户/项目对,那么:

select distinct custno, itemno
from customerprices cp
where exists (select 1
              from customerprices cp2
              where cp2.custno = cp.custno and cp2.itemno = cp.itemno and
                    cp2.validfrom <= cp.validto and
                    cp2.validto >= cp.validto and
                    (cp2.validfrom <> cp.validfrom or cp2.validto <> cp.validto)
             );

这是什么逻辑?首先,它假设在时间上没有完全的重复。其次,它检查是否有任何重叠——包括结尾部分。这应该处理任何重叠(ABBA,ABAB)。

【讨论】:

  • 这正是我所需要的!非常感谢!
【解决方案2】:
select 
    itemno, 
    custno,
    validfrom, 
    validto, 
    price 
from 
    CustomerPrices a
where 
    exists (
        select 1 
        from CustomerPrices b 
        where 
            a.itemno = b.itemno 
            and a.custno = b.custno
            and ((a.validfrom between b.validfrom and b.validto) 
              or (a.validto between b.validfrom and b.validto)) 
    )

【讨论】:

    【解决方案3】:

    您可以将日期类型的条目转换为整数表示形式(请参阅here)。这将使您可以更轻松地比较您的日期条目。

    【讨论】:

    • 你能解释一下吗?任何兼容的 dbms 中的日期比较与整数比较几乎相同。您使用相同的语法和一切。我觉得显式转换数据类型只是在编码和执行过程中浪费了周期。
    • 认为这会更容易与子查询进行比较,提供的 EXISTS 结果更好。
    【解决方案4】:

    不确定,你在寻找什么输出?解释输出。

    它返回最后一行,因为它的valid from 与它的前一行validto 重叠。

    declare @t table(id int identity(1,1),ItemNo int,CustomerNo int
    ,Validfrom date,Validto date,Price int)
    insert into @t VALUES
    (12345,55544, '2016-01-01','2016-05-31',566)
    ,(12345,55544,'2017-03-01','2017-06-01',455)
    ,(12345,55544,'2017-02-01','2017-07-01',641)
    select t1.*
    
    from @t t
    inner join @t t1
     on t.ItemNo=t1.ItemNo
    and t.CustomerNo=t1.CustomerNo
    where 
     (t1.Validfrom<t.Validto)
     and t1.id-t.id=1
    

    【讨论】:

      猜你喜欢
      • 2017-05-08
      • 2013-08-21
      • 2014-01-31
      • 1970-01-01
      • 1970-01-01
      • 2020-03-21
      • 1970-01-01
      • 1970-01-01
      • 2011-05-27
      相关资源
      最近更新 更多