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

时间:2014-03-13 03:55:37

标签: sql sql-server unit-testing date exponential

从2007年1月1日至2011年12月31日,我的产品的单价将固定为原始单价。 从2012年1月1日到2015年12月31日,单价将每年增加2%,因此对于2012年9月11日应为unit price*1.02,并且09/11/2013应为{{ 1}}

我的产品表PRODUCT_T包含Product_ID和Unit_Price等信息。

到目前为止,我有:

(unit price*1.02)*1.02

我的主要错误是,如果我需要创建另一个列甚至另一个表来存储指数单价,或者我是否可以使用if else语句并只保留一列来存储单价。上面代码的问题是它不允许我一次更新两个表(我已经搜索了如何更新两个表,但我仍然没有接近完成这个问题)

我不确定是否需要使用触发器/程序,或者是否可以通过其他方式解决。

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'` 谢谢你真的有帮助,但我还有一些小错误,我仍然需要纠正。我需要的最终输出是产品ID,产品描述,(产品名称)和单价。因此,我想要的是没有列名的那个,而不是列出的单价。 我执行所有这些时的结果:

*UPDATE 03/13/2014 1:14 AM

我猜是没有列名是因为我没有dbo.RealPrice的别名?但我从来没有使用过CREATE FUNCTIONS,所以我试图寻找所有这些意味着什么。 我还发现no列名中的数字是第一个产品(Cleaner)的单位价格乘以1.02,Fire中的1.04和水中的1.06。我想要的是1.02的一切,但我也不确定你在哪里设置自定义日期的值。我的是2012-09-11所以乘数应该是1.02。

这是我从原版更新的代码,我不确定我是否需要这里的所有内容。

PRODUCT_ID    PRODUCT_DESCRIPTION    UNIT_PRICE    (no column name)
    1              Cleaner             4.99            5.089800
    2              Fire                3.99            4.149600
    3              Water               7.99            8.469400

1 个答案:

答案 0 :(得分:0)

我不确定您的示例在此处发布了多少简化,但是我使用POWER功能来解决此问题 - 然后您可以将输出用作computed column或简单地使用在更新声明中。我已经创建了一个函数来说明一般情况:

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)

注意,这个逻辑可能很简单,可以在没有函数的计算列定义中使用,这有助于偏移this potential performance issue,但我将其作为函数包含,因为您可以选择使用许多地方它。或者,您可能希望将其转换为表值函数或视图以提高性能。

如果我们在表中添加一些额外的值,则可以运行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

所以你可以看到我只是简单地使用CASE语句来计算你的POWER和DATEDIFF的答案,虽然我已经使用了静态值1.02(不确定你的静态值是否是静态的,或者应该从在其他地方)。