sql中的case语句对齐和清理

Posted

技术标签:

【中文标题】sql中的case语句对齐和清理【英文标题】:case statement alignment and cleanup in sql 【发布时间】:2019-09-22 15:17:04 【问题描述】:

使用案例陈述解决了业务需求。 case 语句在多个日期属性中是相同的。我知道 case 语句一次只对单个属性起作用,并使用动态 sql 使其重复,但我们不想使用动态 sql。 有没有办法简化 case 语句,使其至少看起来重复且更易于理解。有什么想法吗?

CASE 
   WHEN Status IN ('Denied','Partial Approval') and NotificationDate <> '1900-01-01' AND NotificationDate < Requestdate THEN 'Error'
   WHEN Status IN ('Denied','Partial Approval') and NotificationDate >= RequestDate THEN 
   CASE

            when Type in ('Non-Urgent Preservice','Non-Urgent Concurrent') AND DateDiff(d,RequestDate,NotificationDate) <= 15 then  'Y'         
            when Type = 'Post Service' AND DateDiff(d,RequestDate,NotificationDate) <= 30 then 'Y'    
            when Type = 'Urgent Preservice' AND DateDiff(d,RequestDate,NotificationDate) <= 3 then 'Y'
            when Type = 'Urgent Concurrent' AND DateDiff(d,RequestDate,NotificationDate) <= 3 then 'Y'  
   ELSE 'N'
   END
ELSE 
CASE WHEN Status IN ('Denied','Partial Approval') and NotificationDate IS NULL THEN 
   CASE

            when Type in ('Non-Urgent Preservice','Non-Urgent Concurrent') AND DateDiff(d,RequestDate, getdate()) > 15 then  'N'
            when Type = 'Post Service' AND DateDiff(d,RequestDate, getdate()) > 30 then 'N'
            when Type = 'Urgent Preservice' AND DateDiff(d,RequestDate, getdate()) > 3 then 'N'
            when Type = 'Urgent Concurrent' AND DateDiff(d,RequestDate, getdate()) > 3 then 'N'
   ELSE ''
   END
ELSE 'N/A'

【问题讨论】:

Case 语句可以移动到子查询的 where 子句中。如果可行,您可以按日期范围分组,而不是按日期范围重复其他所有内容。 【参考方案1】:

对于重复的部分,可以使用cross apply给表达式命名:

select . . .,
      (case when Status in ('Denied', 'Partial Approval') and NotificationDate <> '1900-01-01' and NotificationDate < Requestdate 
            then 'Error'
            when Status in ('Denied', 'Partial Approval') and NotificationDate >= RequestDate 
            then v.y_or_n 
            else 'N'
       end)
from t cross apply
     (values (case when Type in ('Non-Urgent Preservice', 'Non-Urgent Concurrent') and DateDiff(day, RequestDate, NotificationDate) <= 15 
                   then  'Y'         
                   when Type = 'Post Service' and DateDiff(day, RequestDate, NotificationDate) <= 30
                   then 'Y'    
                   when Type = 'Urgent Preservice' and DateDiff(day, RequestDate, NotificationDate) <= 3
                   then 'Y'
                   when Type = 'Urgent Concurrent' and DateDiff(day, RequestDate, NotificationDate) <= 3
                   then 'Y'  
                   else 'N'
              end)
         ) v(y_or_n)

【讨论】:

如果我想使用其他需要使用的日期属性而不是通知日期怎么办?我是否再次交叉申请新的日期?? @user1672315k 。 . .我不明白你的问题。您可以采用 select 中的任何表达式,并将其包含在带有名称的 values() 子句中——它只会被计算一次。【参考方案2】:

实际上,Case when 确实只允许在单个字段上使用选项,但您也可以根据条件进行操作,例如

case 
   when ( SomeCondition And AnotherCondition AND Third ) 
      then 'This Answer'
   when (TotallyDifferent OR ( SomeOther AND AlsoThis)) 
      then 'Second Answer'
   when (AnyOther And AnotherDifferent) 
      then 'Third'
   else 
      'Neither of other conditions' 
end

因此,您可以继续添加“WHEN/THEN”条件。它们可能会变得冗长,因为您确实有

的条件
Status IN ('Denied','Partial Approval')

用于多个。它可以在每个 WHEN 部分中重复。现在,只要考虑一下,无论哪个 WHEN 条件符合第一个 WINS 条件,所以具体的顺序很重要。

【讨论】:

以上是关于sql中的case语句对齐和清理的主要内容,如果未能解决你的问题,请参考以下文章

sql2005中的case when语句怎么用啊?请写出一个常见的例子

SQL查询语句SELECT中带有case when嵌套子查询判断的问题

SQL中的条件判断语句(case when zhen if,ifnull)用法

where 子句中的 case 语句 - SQL Server

在 SQL Server 中的 case 语句中寻找解决方案

PL/SQL 中 CASE 语句中的堆栈条件