2009-12-27 80 views
0

需要幫助我有兩個表:優化更新語句

create table CurrentDay (
ID int identity primary key, 
ssn varchar(10), 
val money, 
CheckDate datetime, 
CurrentStatus tinyint) 

create table PreviousDay (
ID int identity primary key, 
ssn varchar(10), 
val money, 
CheckDate datetime, 
CurrentStatus tinyint) 

我需要這個值更新域CurrentDay.CurrentStatus:

  • 111,如果在PreviousDay.ssn是一樣的SSN如當前日期,並且如果PreviousDay的val與CurrentDay中的相同;
  • 112,如果在PreviousDay.ssn中與CurrentDay中的相同,並且如果PreviousDay的val大於CurrentDay中的值;
  • 113,如果在PreviousDay.ssn中與CurrentDay中的相同,並且如果PreviousDay的val小於CurrentDay中的值;
  • 114,如果沒有PreviousDay.ssn與當前日期相同,即CurrentDay中只有ssn(這是今天的信息)。

我寫了一些查詢,但我希望找到其他方式來執行此任務使用PreviousDay和CurrentDay表之間只有一個連接。顯然,這不是一個很幸運的那種......這是我的變種:

Update CurrentDay 
Set CurrentStatus=case 
when exists (select PreviousDay.ID from PreviousDay 
where PreviousDay.ssn=CurrentDay.ssn AND 
PreviousDay.val=CurrentDay.val AND 
PreviousDay.CheckDate=DATEADD(day,-1,CurrentDay.CheckDate)) 
then 111 
when exists (select PreviousDay.ID from PreviousDay 
where PreviousDay.ssn=CurrentDay.ssn AND 
PreviousDay.val>CurrentDay.val AND 
PreviousDay.CheckDate=DATEADD(day,-1,CurrentDay.CheckDate)) 
then 112 
when exists (select PreviousDay.ID from PreviousDay 
where PreviousDay.ssn=CurrentDay.ssn AND 
PreviousDay.val<CurrentDay.val AND 
PreviousDay.CheckDate=DATEADD(day,-1,CurrentDay.CheckDate)) 
then 113 
when exists (select PreviousDay.ID from PreviousDay 
where PreviousDay.ssn!=CurrentDay.ssn AND 
PreviousDay.CheckDate=DATEADD(day,-1,CurrentDay.CheckDate)) 
then 114 
end; 

下面是其他的查詢,但在這種情況下,因爲只有我不能用價值114更新CurrentDay.CurrentStatus' fieid匹配的SSN行的兩個表中:

Set Currentday.CurrentStatus=(select 111 where PreviousDay.val=CurrentDay.val union all select 112 where and PreviousDay.val>CurrentDay.val union all select 113 where and PreviousDay.val<CurrentDay.val /*union all select 114 */) from PreviousDay join CurrentDay on PreviousDay.ssn=CurrentDay.ssn and PreviousDay.CheckDate=DATEADD(day,-1,CurrentDay.CheckDate)

你有任何其他的想法?

回答

1

喜歡的東西:

UPDATE 
    C 
Set 
    CurrentStatus = CASE 
      WHEN P.val = C.val THEN 111 
      WHEN P.val > C.val THEN 112 
      WHEN P.val < C.val THEN 113 
      ELSE 114 ---this works because if P.VAL is null, that is no matching row 
     END 
FROM 
    CurrentDay C 
    LEFT JOIN 
    PreviousDay P On C.ssn = P.ssn AND P.CheckDate = DATEADD(day, -1, C.CheckDate)) 
+2

我建議在114上明確表示 - 狀態114意味着SSN在前一天不存在,所以它應該說「什麼時候P.val IS NULL」;這對於稍後閱讀代碼的人來說更好。 – 2009-12-27 17:19:27

+0

謝謝 - 這就是我需要的! – Balend 2009-12-27 17:25:34

1

你可以嘗試這樣的事情

​​

這是我的測試代碼。利用val條目爲BeforeDay查看它是否有效,或者完全刪除PreviousDay的條目以查看新的條目選項。

DECLARE @CurrentDay table (
ID int identity primary key, 
ssn varchar(10), 
val money, 
CheckDate datetime, 
CurrentStatus tinyint) 



DECLARE @PreviousDay table (
ID int identity primary key, 
ssn varchar(10), 
val money, 
CheckDate datetime, 
CurrentStatus tinyint) 

INSERT INTO @CurrentDay (ssn, val, CheckDate) SELECT 1, 1, '02 Jan 2009' 
INSERT INTO @PreviousDay (ssn, val, CheckDate) SELECT 1, 0, '01 Jan 2009' 

UPDATE @CurrentDay 
     SET CurrentStatus = 
     CASE 
      WHEN cd.val = pd.val THEN 111 
      WHEN cd.val < pd.val THEN 112 
      WHEN cd.val > pd.val THEN 113 
      WHEN pd.val IS NULL THEN 114 
     END 
FROM @CurrentDay cd LEFT JOIN 
     @PreviousDay pd ON cd.ssn = pd.ssn 
         AND cd.CheckDate = DATEADD(d, 1, pd.CheckDate) 

SELECT * FROM @CurrentDay 
+0

爲GBN相同的註釋 - 應該在114碼明確(包括空校驗)。我可以發誓,當我向上投票時你有了NULL檢查,現在不是。 – 2009-12-27 17:22:35

+0

改變了它,類似的東西? – 2009-12-27 17:24:37

+0

無論哪種方式,它都能正常工作,只需使用NULL檢查自行記錄。 – 2009-12-27 17:28:45