2014-03-13 69 views
0

從2007年1月1日至2011年12月31日,無論原始單價如何,我的產品單價都將固定。 從01/01/2012到12/31/2015,單位價格將每年增長2%,因此對於2012年9月11日應該是unit price*1.02,和2013年9月11日應該是(unit price*1.02)*1.02SQL 2008:每年固定價格然後按指數增加價格,每年

我的產品表PRODUCT_T具有Product_ID和Unit_Price等信息。

到目前爲止,我有:

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'` 

我的主要錯誤是,如果我需要創建另一列或甚至另一個表來存儲指數單價,或者如果我可以使用,如果else語句,並保持只有一列來存儲單價。上面的代碼的問題是,它不會讓我一次更新兩個表(我已經搜索如何更新兩個表,但我仍然沒有接近完成這個問題)

我不知道如果我需要爲此使用觸發器/過程,或者可以通過其他方式解決。

*UPDATE 03/13/2014 1:14 AM 謝謝你真正幫助,但我有幾個小錯誤,我仍然需要糾正。我需要的最終產品是產品ID,產品說明,(產品名稱)和單位價格。所以,而不是在那裏列出的單位價格,我想要沒有列名稱的人來代替。 當我執行所有這一切的結果是:

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 

我猜的沒有列名是因爲我沒有爲dbo.RealPrice別名?但是我從來沒有使用過CREATE FUNCTIONS,所以我試圖去尋找所有這些意思。 我還發現no欄名中的數字乘以第一個產品(清潔劑)的單位價格1.02,Fire中的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 
+0

我建議用正確的大小寫來重新格式化你的文章。這很難閱讀。 – attila

回答

0

我不知道有多少你的例子已經被簡化,張貼在這裏,但我會用冪函數來解決這個 - 那麼你可以使用輸出爲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語句來計算與電源你的答案見和DATEDIFF,儘管我已經使用了1.02的靜態值(不確定你的是靜態的還是應該從其他地方繪製)。

+0

是的1.02是靜態的,我更新了我的問題與幾個小錯誤 – Selectful

+0

自定義日期是在你的表中的字段 - 但是我使用的更新語句將它們設置不同,以證明這一點。將我的更新聲明替換爲適合您的更新聲明,您應該看到所需的結果。我也注意到你已經有了這個函數,而且select語句沒有使用它 - 我試圖展示兩種方法來做這件事,因此我相信這個混淆。這說明了嗎? – DaveGreen

+0

是的,我得到它的工作!你會碰巧知道哪個實體我會用ALIAS來替換(沒有列名)?我認爲這是ELSE之後和第二個表中的FROM之前的計算語句,但是當我在CUSTOM_DATE之後執行AS時,它給了我一個錯誤)+1) – Selectful