выравнивание и очистка case case в sql - PullRequest
0 голосов
/ 22 сентября 2019

Решено бизнес-требование с использованием описания случая.Оператор 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'

Ответы [ 2 ]

1 голос
/ 22 сентября 2019

Для повторяющейся части вы можете использовать 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)
0 голосов
/ 22 сентября 2019

На самом деле Случай, когда разрешается опция только для одного поля, но вы также можете сделать это на основе таких условий, как

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

Итак, вы можете просто продолжать добавлять условия «КОГДА / ТО».Они могут стать длиннее, поскольку у вас есть условия

Status IN ('Denied','Partial Approval')

, которые используются в нескольких.Это может быть повторено в каждой части WHEN.Теперь просто подумайте, какое бы условие ни относилось к первому WINS, особый порядок важен.

...