首页 > 解决方案 > 如何用用例构造条件更新

问题描述

我必须写一个更新查询。如果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

当我执行它时,我得到:

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

标签: sqlsql-servertsql

解决方案


它是一个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());

然而,这不是 sargable 即不能使用任何索引,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 有很大的影响

推荐阅读