如何使用case构造条件更新



我必须编写一个更新查询。如果special_member账户没有被取消,那么在where条款中,我必须使用这个条件,在到期日后增加15天的宽限期,并将其与今天的日期进行比较:

Convert(date,MEMBER_EXPIRY_DATE + 15) >= Convert(date,GETDATE())

如果会员资格被取消,那么我必须将实际到期日期与今天的日期进行比较。这是我的完整查询:

UPDATE SPECIAL_MEMBER SET SAVINGS_PERCENT = 10, ORDER_COUNT = 1 
WHERE SPECIAL_MEMBER = '4382' AND CASE WHEN (CANCELLED = 0) THEN  
Convert(date,MEMBER_EXPIRY_DATE + 15) >= Convert(date,GETDATE())
ELSE  (Convert(date,MEMBER_EXPIRY_DATE) >= Convert(date,GETDATE())) END

当我执行它时,我得到:

">"附近的语法不正确。

它是一个case表达式,而不是语句。因此,它只能返回一个值,即不能包含任何条件。只需将您要比较的值移动到case之外,例如

UPDATE SPECIAL_MEMBER SET
SAVINGS_PERCENT = 10
, ORDER_COUNT = 1 
WHERE SPECIAL_MEMBER = '4382'
AND CASE WHEN CANCELLED = 0
THEN CONVERT(DATE,DATEADD(DAY,15,MEMBER_EXPIRY_DATE)) 
ELSE CONVERT(DATE,MEMBER_EXPIRY_DATE) END >= CONVERT(DATE,GETDATE());

然而,这是不可行的,即不能使用MEMBER_EXPIRY_DATE上的任何索引,因此我建议将逻辑切换到

UPDATE SPECIAL_MEMBER SET
SAVINGS_PERCENT = 10
, ORDER_COUNT = 1 
WHERE SPECIAL_MEMBER = '4382'
AND MEMBER_EXPIRY_DATE >= CONVERT(DATE,DATEADD(DAY,CASE WHEN CANCELLED = 0 THEN -15 ELSE 0 END,GETDATE())) 

注:

  • 日期不是自然添加的,请使用dateadd函数
  • 这并没有什么动态性——动态SQL完全不同
  • 使用良好的布局和一致的大小写对读取SQL有很大的不同

您可以忽略CASE并使用如下方法:

UPDATE SPECIAL_MEMBER 
SET SAVINGS_PERCENT = 10
, ORDER_COUNT = 1 
WHERE SPECIAL_MEMBER = '4382' 
AND ( CANCELLED = 0 AND DATEADD(dd,15,CONVERT(DATE, MEMBER_EXPIRY_DATE)) >= CONVERT(DATE,GETDATE())
OR CANCELLED != 0 AND CONVERT(DATE,MEMBER_EXPIRY_DATE) >= CONVERT(DATE,GETDATE())) 

最新更新