【问题标题】:Can you use CASE inside another CASE and DATEADD() function in a T-SQL statement?您可以在 T-SQL 语句中的另一个 CASE 和 DATEADD() 函数中使用 CASE 吗?
【发布时间】:2020-01-03 15:27:55
【问题描述】:

我正在创建一个查询,它将报告工具和设备及其所需的维护状态。

我有一列当前正在使用NextDateDue 列,并检查它与当前日期是否已过期。在查看数据后,此列不是很可靠,所以我想通过 LastDateDue(上次维护完成日期)查看维护频率(例如两年一次、每周、每月),将该频率添加到LastDateDue 并检查该日期与当前日期以确定过期或就绪。

这是我当前的代码:

SELECT 
    MS.MaintCompletionDate, RF.ObjectType, RD.ResourceName, 
    MRB.MaintenanceReqName, MS.NextDateDue,
    CASE
        WHEN MS.NextDateDue < GETDATE() THEN 'PAST DUE'
        WHEN MS.NextDateDue IS NULL THEN 'N/A'
        ELSE 'READY'
    END AS MaintenanceStatus
FROM
    CamstarSch.ResourceDef RD
INNER JOIN 
    CamstarSch.MaintenanceStatus MS ON RD.ResourceId = MS.ResourceId
INNER JOIN 
    CamstarSch.ResourceFamily RF ON RF.ResourceFamilyId = RD.ResourceFamilyId
INNER JOIN 
    CamstarSch.AssignedMaintReq AMR ON AMR.AssignedMaintReqId = MS.AssignedMaintReqId
INNER JOIN 
    CamstarSch.MaintenanceReq MR ON AMR.MaintenanceReqId = MR.MaintenanceReqId
INNER JOIN 
    CamstarSch.MaintenanceReqBase MRB ON MRB.MaintenanceReqBaseId = MR.MaintenanceReqBaseId
ORDER BY 
    NextDateDue DESC;

我想以我认为看起来像这样的方式设置我的陈述:

   WHEN DATEADD(CASE WHEN MRB.MaintenanceReqName IS 'Bi-Annual' THEN 'month, 6,' MS.LastDateDue) < GETDATE() THEN 'PAST DUE'

每种频率都有更多的 WHEN 子句。

这可能吗?我是不是走错路了?

【问题讨论】:

  • 来自CASE (Transact-SQL) - Remarks“SQL Server 只允许在 CASE 表达式中嵌套 10 级。”。 (另请注意,它是CASE 表达式Case(Switch) 语句在 T-SQL 中不存在。)
  • 注意:“bi”表示 2,而不是一半。 “两年一次”是指每 2 年一次。 “半年”是指每半年(6个月)。不要使用错误的术语给您的系统造成混乱。

标签: sql sql-server case ssms dateadd


【解决方案1】:

根据我对您问题的理解,这就是您想要的:

WHEN
  CASE MRB.MaintenanceReqName 
    WHEN 'Bi-Annual' THEN DATEADD(month, 6, MS.LastDateDue) 
    WHEN 'Monthly' THEN DATEADD(month, 1, MS.LastDateDue) 
    WHEN 'Weekly' THEN DATEADD(week, 1, MS.LastDateDue)  
  END < GETDATE() 
THEN 'PAST DUE'

【讨论】:

    【解决方案2】:

    你可以把一个箱子放在另一个箱子里。或者,您可以将多个子句放入外部案例中。或者,如果您有重复执行的操作(可能根据维护频率确定到期日期),请创建一个函数。选择更适合您的数据并提高可维护性的版本。我认为,鉴于上面的例子,一个函数可能是最好的选择。 功能:

    CREATE FUNCTION dbo.GetDueDate  (@MaintenanceReqName varchar(50), @LastDateDue date)  
    RETURNS date  
    AS  
    BEGIN
     DECLARE @NextDueDate date;
     SELECT @NextDueDate = CASE
        WHEN MRB.MaintenanceReqName IS 'Quarterly' THEN DATEADD(month, 3, @LastDateDue)    
        WHEN MRB.MaintenanceReqName IS 'Bi-Annual' THEN DATEADD(month, 6, @LastDateDue)
        WHEN MRB.MaintenanceReqName IS 'Annual' THEN DATEADD(year, 1, @LastDateDue)
        ELSE DATEADD(day, 30, @LastDateDue)
     END NextDueDate
     return @NextDueDate
    END
    ....
     WHEN GetDueDate(MRB.MaintenanceReqName,MS.LastDateDue) < GETDATE() THEN 'PAST DUE'
    

    多个子句:

    CASE
        WHEN MS.NextDateDue < GETDATE() AND MRB.MaintenanceReqName IS 'Bi-Annual' THEN 'PAST DUE'
        WHEN MS.NextDateDue IS NULL THEN 'N/A'
        ELSE 'READY'
    END AS MaintenanceStatus
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-30
      • 2018-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多