2009-12-27 60 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