SQL 2008:每年固定价格,然后每年以指数形式增加价格

SQL 2008:每年固定价格,然后每年以指数形式增加价格,sql,sql-server,unit-testing,date,exponential,Sql,Sql Server,Unit Testing,Date,Exponential,从2007年1月1日到2011年12月31日,我的产品的单价将固定为原始单价。 从2012年1月1日到2015年12月31日,单价将每年增加2%,因此2012年9月11日的单价应为单价*1.02,2013年9月11日的单价应为(单价*1.02)*1.02 我的产品表product\T包含产品ID和单价等信息 到目前为止,我已经: CREATE TABLE PRODUCT_TIMESTAMP_T ( PRODUCT_ID INT, START_VALID_DATE DATE, END_VALID_

从2007年1月1日到2011年12月31日,我的产品的单价将固定为原始单价。 从2012年1月1日到2015年12月31日,单价将每年增加2%,因此2012年9月11日的单价应为
单价*1.02
,2013年9月11日的单价应为
(单价*1.02)*1.02

我的产品表product\T包含产品ID和单价等信息

到目前为止,我已经:

CREATE TABLE PRODUCT_TIMESTAMP_T
(
PRODUCT_ID INT,
START_VALID_DATE DATE,
END_VALID_DATE DATE,
START_EXPONENTIAL_DATE DATE,
END_EXPONENTIAL_DATE DATE,
CUSTOM_DATE DATE,
UNIT_PRICE DECIMAL (13,4)
);

ALTER TABLE PRODUCT_TIMESTAMP_T ADD FOREIGN KEY (PRODUCT_ID) REFERENCES PRODUCT_T.PRODUCT_ID

INSERT INTO PRODUCT_TIMESTAMP_T (PRODUCT_ID)
VALUES (1),(2),(3),(4)

UPDATE PRODUCT_TIMESTAMP_T
SET START_VALID_DATE = '2007-01-01'

UPDATE PRODUCT_TIMESTAMP_T
SET END_VALID_DATE = '2011-12-31'

UPDATE PRODUCT_TIMESTAMP_T
SET START_EXPONENTIAL_DATE = '2012-01-01'

UPDATE PRODUCT_TIMESTAMP_T
SET END_EXPONENTIAL_DATE = '2015-12-31'

UPDATE PRODUCT_TIMESTAMP_T 
SET PRODUCT_T.UNIT_PRICE = PRODUCT_TIMESTAMP_T.UNIT_PRICE
WHERE CUSTOM_DATE < START_EXPONENTIAL_DATE

UPDATE PRODUCT_TIMESTAMP_T
SET REAL_PRICE = UNIT_PRICE*1.02
WHERE CUSTOM_DATE < '2013-01-01'`
我猜没有列名是因为我没有dbo.RealPrice的别名?但我从来没有使用过CREATE函数,所以我试图寻找所有这些都意味着什么。 我还发现,no列名称中的数字是第一种产品(清洁剂)的单价乘以1.02,火中乘以1.04,水中乘以1.06。我想要的是1.02,但我也不确定自定义日期的值设置在哪里。我的是2012-09-11,所以乘数应该是1.02

这是我从原始版本更新的代码,我不确定我是否需要这里的所有东西

CREATE TABLE PRODUCT_TIMESTAMP_T
(
PRODUCT_ID INT,
START_VALID_DATE DATE,
END_VALID_DATE DATE,
START_EXPONENTIAL_DATE DATE,
END_EXPONENTIAL_DATE DATE,
CUSTOM_DATE DATE,
UNIT_PRICE DECIMAL (13,4)
);


INSERT INTO PRODUCT_TIMESTAMP_T (PRODUCT_ID)
VALUES (1),(2),(3),(4)

UPDATE PRODUCT_TIMESTAMP_T
SET START_VALID_DATE = '2007-01-01'

UPDATE PRODUCT_TIMESTAMP_T
SET END_VALID_DATE = '2011-12-31'

UPDATE PRODUCT_TIMESTAMP_T
SET START_EXPONENTIAL_DATE = '2012-01-01'

UPDATE PRODUCT_TIMESTAMP_T
SET END_EXPONENTIAL_DATE = '2015-12-31'

GO
CREATE FUNCTION dbo.RealPrice
       (@START_EXPONENTIAL_DATE date,
        @CUSTOM_DATE date, 
        @START_UNIT_PRICE DECIMAL (13,4),
        @ANNUAL_INCREASE DECIMAL (13,4))
RETURNS DECIMAL (13,4)
AS BEGIN
DECLARE @CALCULATED_UNIT_PRICE DECIMAL (13,4)
IF @CUSTOM_DATE < @START_EXPONENTIAL_DATE RETURN @START_UNIT_PRICE 
SET @CALCULATED_UNIT_PRICE = @START_UNIT_PRICE * POWER( @ANNUAL_INCREASE , DATEDIFF(YY,@START_EXPONENTIAL_DATE,@CUSTOM_DATE)+1)
RETURN @CALCULATED_UNIT_PRICE
END
GO

SELECT dbo.RealPrice('2012-01-01','9/11/2012',10,1.02) AS REAL_PRICE

UPDATE PRODUCT_TIMESTAMP_T
SET UNIT_PRICE = 1,CUSTOM_DATE = DATEADD(yy,PRODUCT_ID-1,START_EXPONENTIAL_DATE)

SELECT  PRODUCT_T.PRODUCT_ID,
        PRODUCT_DESCRIPTION,
        PRODUCT_T.UNIT_PRICE
,CASE WHEN START_EXPONENTIAL_DATE < START_VALID_DATE THEN PRODUCT_T.UNIT_PRICE
ELSE PRODUCT_T.UNIT_PRICE * POWER( 1.02 , DATEDIFF(YY,START_EXPONENTIAL_DATE,CUSTOM_DATE)+1) END
 FROM PRODUCT_TIMESTAMP_T, PRODUCT_T
 WHERE PRODUCT_T.PRODUCT_ID = PRODUCT_TIMESTAMP_T.PRODUCT_ID
 AND PRODUCT_T.UNIT_PRICE IS NOT NULL
创建表产品\u时间戳\u T
(
产品ID INT,
开始日期有效日期,
结束日期有效日期,
开始日期,
结束日期,
自定义日期,
单价小数(13,4)
);
插入产品\u时间戳\u T(产品\u ID)
值(1)、(2)、(3)、(4)
更新产品\u时间戳\u T
设置开始有效日期='2007-01-01'
更新产品\u时间戳\u T
设置结束有效日期='2011-12-31'
更新产品\u时间戳\u T
设置开始日期='2012-01-01'
更新产品\u时间戳\u T
设置结束日期='2015-12-31'
去
创建函数dbo.RealPrice
(@START_指数日期,
@自定义日期,
@起始单价小数(13,4),
@年增长率(十进制(13,4))
返回十进制(13,4)
作为开始
声明计算单价小数点后(13,4)
如果@CUSTOM_DATE<@START_index_DATE返回@START_单价
设置@CALCULATED_UNIT_PRICE=@START_UNIT_PRICE*功率(@ANNUAL_INCREASE,DATEDIFF(YY,@START_Index_DATE,@CUSTOM_DATE)+1)
返回@计算的单位价格
结束
去
选择dbo.RealPrice('2012-01-01','9/11/2012',10,1.02)作为实际价格
更新产品\u时间戳\u T
设置单价=1,自定义日期=日期添加(yy,产品ID-1,开始日期)
选择PRODUCT\T.PRODUCT\u ID,
产品说明,
产品单价
,开始日期<开始有效日期>产品单价时的情况
其他产品单位价格*功率(1.02,日期差(YY,开始日期,自定义日期)+1)结束
从产品\u时间戳\u T,产品\u T
其中PRODUCT\u T.PRODUCT\u ID=PRODUCT\u时间戳\u T.PRODUCT\u ID
并且产品单价不为空

我不确定您的示例在这里简化了多少,但是我会使用幂函数来解决这个问题-然后您可以将输出用作一个或仅在update语句中使用。我创建了一个函数来说明一般情况:

CREATE FUNCTION dbo.RealPrice (@START_EXPONENTIAL_DATE date,
        @CUSTOM_DATE date, 
        @START_UNIT_PRICE DECIMAL (13,4),
        @ANNUAL_INCREASE DECIMAL (13,4))
RETURNS DECIMAL (13,4)
AS BEGIN
DECLARE @CALCULATED_UNIT_PRICE DECIMAL (13,4)
IF @CUSTOM_DATE < @START_EXPONENTIAL_DATE RETURN @START_UNIT_PRICE -- Otherwise we can get calculated deflation
SET @CALCULATED_UNIT_PRICE = @START_UNIT_PRICE * POWER( @ANNUAL_INCREASE , DATEDIFF(YY,@START_EXPONENTIAL_DATE,@CUSTOM_DATE)+1)
RETURN @CALCULATED_UNIT_PRICE
END
GO

SELECT dbo.RealPrice('2012-01-01','9/11/2013',10,1.02)
创建函数dbo.RealPrice(@START\u index\u DATE,
@自定义日期,
@起始单价小数(13,4),
@年增长率(十进制(13,4))
返回十进制(13,4)
作为开始
声明计算单价小数点后(13,4)
如果@CUSTOM\u DATE<@START\u index\u DATE返回@START\u单价——否则我们可以得到计算得出的通货紧缩
设置@CALCULATED_UNIT_PRICE=@START_UNIT_PRICE*功率(@ANNUAL_INCREASE,DATEDIFF(YY,@START_Index_DATE,@CUSTOM_DATE)+1)
返回@计算的单位价格
结束
去
选择dbo.RealPrice('2012-01-01','9/11/2013',10,1.02)
注意,这个逻辑可能变得足够简单,可以在没有函数的计算列定义中使用,这有助于偏移,但我将它作为函数包括在内,因为您可以选择在许多地方使用它。或者,您可能希望将其转换为表值函数或视图以提高性能

如果向表中添加一些附加值,则可以运行select语句中的简单示例:

UPDATE PRODUCT_TIMESTAMP_T
SET UNIT_PRICE = 1,CUSTOM_DATE = DATEADD(yy,PRODUCT_ID-1,START_EXPONENTIAL_DATE)

SELECT  PRODUCT_ID ,
        START_VALID_DATE ,
        END_VALID_DATE ,
        START_EXPONENTIAL_DATE ,
        END_EXPONENTIAL_DATE ,
        CUSTOM_DATE ,
        UNIT_PRICE
,CASE WHEN START_EXPONENTIAL_DATE < START_VALID_DATE THEN UNIT_PRICE
ELSE UNIT_PRICE * POWER( 1.02 , DATEDIFF(YY,START_EXPONENTIAL_DATE,CUSTOM_DATE)+1) END
 FROM PRODUCT_TIMESTAMP_T
更新产品\u时间戳\u T
设置单价=1,自定义日期=日期添加(yy,产品ID-1,开始日期)
选择产品标识,
开始有效日期,
结束有效日期,
开始日期,
结束日期,
定制日期,
单价
,开始日期<开始有效日期>单价时的情况
其他单价*功率(1.02,日期差(YY,开始日期,自定义日期)+1)结束
从产品\u时间戳\u T

所以你可以看到,我只是用CASE语句来计算你的答案,并使用POWER和DATEDIFF,尽管我使用了静态值1.02(不确定你的是静态值还是应该从其他地方提取)。

我建议用正确的大小写来重新格式化你的帖子。这很难理解。是的,1.02是静态的,我用一些小错误更新了我的问题。Stom date是您表格中的一个字段,但是我使用的更新语句将它们设置为不同的值以证明这一点。将我的update语句替换为适合您的语句,您将看到所需的结果。我还注意到,您既有函数,也有select语句,而select语句并没有使用它-我试图展示两种方法来实现这一点,因此我相信会有混淆。这说明了吗?是的,我成功了!您是否知道我将使用ALIAS替换哪个实体(无列名)?我以为这是您显示的第二个表中在ELSE之后和before FROM之前的计算语句,但当我执行AS after CUSTOM_DATE)+1)您需要AS after the END-…CUSTOM_DATE)+1)END AS MyNewColumnName FROM。。。
UPDATE PRODUCT_TIMESTAMP_T
SET UNIT_PRICE = 1,CUSTOM_DATE = DATEADD(yy,PRODUCT_ID-1,START_EXPONENTIAL_DATE)

SELECT  PRODUCT_ID ,
        START_VALID_DATE ,
        END_VALID_DATE ,
        START_EXPONENTIAL_DATE ,
        END_EXPONENTIAL_DATE ,
        CUSTOM_DATE ,
        UNIT_PRICE
,CASE WHEN START_EXPONENTIAL_DATE < START_VALID_DATE THEN UNIT_PRICE
ELSE UNIT_PRICE * POWER( 1.02 , DATEDIFF(YY,START_EXPONENTIAL_DATE,CUSTOM_DATE)+1) END
 FROM PRODUCT_TIMESTAMP_T