t-sql:检查给定日期是否在每年的12月15日到1月10日的折扣期间

时间:2013-10-02 00:00:45

标签: sql-server tsql date

表包含DiscountStart和DiscountEnd列。两列都包含Month +'/'+ Day值。

 Product     DiscountStart     DiscountEnd     Rate
 --------------------------------------------------
 Product1     'Dec/10'          'Jan/05'        10% 
 Product2     'Nov/01           'Dec/31'        12% 
 Product3     'May/01'          'Jun/30'        08% 
 Product4     'Sep/01'          'Sep/15'        05%

如果购买日期在购买年的DiscountStartDiscountEnd期之间,我需要对产品应用折扣率。请帮忙。

3 个答案:

答案 0 :(得分:0)

不确定为什么要存储这样的日期范围,但我建议使用 WHERE <PurchaseDate> BETWEEN DiscountStart and DiscountEnd一般。我会解析3个字母的代码并用数字替换它,然后添加年份。像这样:

SELECT p.Price * DiscTbl.Rate DiscountedRate, *
FROM 
(
    SELECT
        Product, 
        CASE LEFT(DiscountStart, 3) 
          WHEN 'JAN' THEN '01' 
          WHEN 'FEB' THEN '02'
          WHEN 'MAR' THEN '03'
          .
          .
          .
          ELSE NULL END 
          + RIGHT(DiscountStart, 3) + '/'
          + CAST(DATEPART(YEAR, GETDATE()) AS VARCHAR(4)) AS StartDate
       , 
       CASE LEFT(DiscountEnd, 3) 
          WHEN 'JAN' THEN '01' 
          WHEN 'FEB' THEN '02'
          WHEN 'MAR' THEN '03'
          .
          .
          .
          ELSE NULL END 
          + RIGHT(DiscountEnd, 3) + '/'
          + CAST(DATEPART(YEAR, GETDATE()) AS VARCHAR(4)) AS EndDate,
       Rate
    FROM DiscountTable --Named for the sake of this example
) DiscTbl
join Purchases p --Named for the sake of this example
     on p.Product = DiscTbl.Product 
    and p.PurchaseDate BETWEEN 
                          CASE WHEN DiscTbl.StartDate > DiscTbl.EndDate 
                               THEN DATEADD(YEAR, -1, DiscTbl.StartDate)
                               ELSE DiscTbl.StartDate 
                          END
                       AND DiscTbl.EndDate 

答案 1 :(得分:0)

要获得指定日期的适用折扣,

select
*
from
(
    select 
        product,
        startdate,
        case when (enddate<startdate) then DATEADD(YY,1,enddate)else enddate end enddate,
        rate
    from
        (
            select 
                CONVERT(date, convert(varchar(4),year(getdate()))+'/'+discountstart) as startdate,
                CONVERT(date, convert(varchar(4),year(getdate()))+'/'+discountend) as enddate,
                product, rate from yourtable
            union 
            select 
                CONVERT(date, convert(varchar(4),year(getdate())-1)+'/'+discountstart) as startdate,
                CONVERT(date, convert(varchar(4),year(getdate())-1)+'/'+discountend) as enddate,
                product, rate from yourtable

        ) v
) discounts
where GETDATE() between startdate and enddate

从那里,您可以对购买进行简单的left join,看看是否有任何折扣适用。

答案 2 :(得分:0)

或许这样的事情:

-- test tables and test data

declare @t table(Product char(8),  DiscountStart char(6), DiscountEnd char(6), Rate char(3))
insert @t values
('Product1','Dec/10','Jan/05','10%'),
('Product2','Nov/01','Dec/31','12%'),
('Product3','May/01','Jun/30','08%'),
('Product4','Sep/01','Sep/15','05%')

declare @productlist table(selldate datetime, product char(8))
insert @productlist values('20130101', 'Product1')
insert @productlist values('20130501', 'Product2')
insert @productlist values('20151231', 'Product1')


select pl.selldate, pl.product, coalesce(x.rate, '00%') rate from 
@productlist pl
outer apply
(
 select rate, a,b from
 (
  select rate, convert(datetime, cast(year(pl.selldate) as char(4))+'-' + DiscountStart, 106) a,
  case when convert(datetime, cast(year(pl.selldate) as char(4))+'-' + DiscountEnd, 106) < convert(datetime, cast(year(pl.selldate) as char(4))+'-' + DiscountStart, 106)
  then convert(datetime, cast(year(pl.selldate) + 1 as char(4))+'-' + DiscountEnd, 106) else convert(datetime, cast(year(pl.selldate) as char(4))+'-' + DiscountEnd, 106) end b
   from @t
  where pl.Product = Product
  union all
  select rate, convert(datetime, cast(year(pl.selldate)-1 as char(4))+'-' + DiscountStart, 106) a,
  case when convert(datetime, cast(year(pl.selldate)-1 as char(4))+'-' + DiscountEnd, 106) < convert(datetime, cast(year(pl.selldate)-1 as char(4))+'-' + DiscountStart, 106)
  then convert(datetime, cast(year(pl.selldate) + 1-1 as char(4))+'-' + DiscountEnd, 106) else convert(datetime, cast(year(pl.selldate)-1 as char(4))+'-' + DiscountEnd, 106) end b
  from @t
  where pl.Product = Product
 ) x1
 WHERE pl.selldate between x1.a and x1.b
) x