在另一个 Case 语句中使用 Case 语句的结果

Lea*_*ner 4 t-sql sql-server

我有一个很长的SELECT查询,但我已将相关部分粘贴到此处。

我需要使用我的CASE语句的结果在另一个CASE语句中使用。我正在 SQL Server 中执行此操作。

将非常感谢您的帮助。

SELECT
    CompanyContact.Name AS CompanyName,
    CASE 
       WHEN SUBSTRING(HeadLease.TenantBreakNotice, LEN(HeadLease.TenantBreakNotice), 1) = 'M'
          THEN CONVERT(VARCHAR(10), DATEADD(DD, -365 / (12 / SUBSTRING(HeadLease.TenantBreakNotice, 1, LEN(HeadLease.TenantBreakNotice) - 1)), HeadLease.TenantBreakDate), 103)
       WHEN SUBSTRING(HeadLease.TenantBreakNotice, LEN(HeadLease.TenantBreakNotice), 1) = 'Y'
          THEN CONVERT(VARCHAR(10), DATEADD(DD, -365 * (SUBSTRING(HeadLease.TenantBreakNotice, 1, LEN(HeadLease.TenantBreakNotice) - 1)), HeadLease.TenantBreakDate), 103)
       ELSE HeadLease.TenantBreakNotice
    END AS [TenantBreakNotice],  <-- I need this to be used in the case statement below.
    CASE
       WHEN [TenantBreakNotice] < CONVERT(varchar(10), getdate(), 103)  
          THEN 'Expiry' 
       WHEN [TenantBreakNotice] IS NULL 
          THEN 'Expiry' 
       ELSE 'Break' 
    END AS [LeaseEventType]
FROM 
    HeadLease  
Run Code Online (Sandbox Code Playgroud)

Gor*_*off 6

您不能在select定义它的地方使用列别名。通常的解决方案是重复逻辑(难以维护),使用子查询或 CTE。SQL Server 提供了另一种优雅的解决方案:

SELECT hl.Name AS CompanyName, v.TenantBreakNotice,
       (CASE WHEN v.TenantBreakNotice < CONVERT(varchar(10), getdate(), 103)  THEN 'Expiry' 
             WHEN TenantBreakNotice IS NULL THEN 'Expiry' 
             ELSE 'Break' 
        END) AS [LeaseEventType]

FROM HeadLease hl OUTER APPLY
     (VALUES (CASE WHEN SUBSTRING(hl.TenantBreakNotice, LEN(hl.TenantBreakNotice), 1) = 'M'
                   THEN CONVERT(VARCHAR(10), DATEADD(DAY, -365/(12/SUBSTRING(hl.TenantBreakNotice, 1, LEN(hl.TenantBreakNotice) -1)), hl.TenantBreakDate), 103)
                   WHEN SUBSTRING(hl.TenantBreakNotice, LEN(hl.TenantBreakNotice), 1) = 'Y'
                   THEN CONVERT(VARCHAR(10), DATEADD(DAY, -365*(SUBSTRING(hl.TenantBreakNotice,1, LEN(hl.TenantBreakNotice)-1)), hl.TenantBreakDate), 103)
                   ELSE hl.TenantBreakNotice
              END) v(TenantBreakNotice);
Run Code Online (Sandbox Code Playgroud)

当然,逻辑是不正确的,因为您将日期作为字符串进行比较。然而,这是你需要自己弄清楚的事情。不要将日期转换为日期操作的字符串。而且,您应该将结果输出为 YYYY-MM-DD,以便格式明确。


sas*_*aso 2

使用 CTE(公用表表达式)。在 CTE 中,您可以引用之前 CTE 中的列,因此您可以按照自己的意愿拆分 CASE 逻辑。

例子:

WITH 
    CTE_1 AS 
    (
        SELECT
            *
            ,CASE 
                WHEN SUBSTRING(HeadLease.TenantBreakNotice,LEN(HeadLease.TenantBreakNotice),1) = 'M'
                    THEN CONVERT(VARCHAR(10), DATEADD(DD,-365/(12/SUBSTRING(HeadLease.TenantBreakNotice,1,LEN(HeadLease.TenantBreakNotice)-1)),HeadLease.TenantBreakDate), 103)
                WHEN SUBSTRING(HeadLease.TenantBreakNotice,LEN(HeadLease.TenantBreakNotice),1) = 'Y'
                    THEN CONVERT(VARCHAR(10), DATEADD(DD,-365*(SUBSTRING(HeadLease.TenantBreakNotice,1,LEN(HeadLease.TenantBreakNotice)-1)),HeadLease.TenantBreakDate), 103)
            ELSE 
                HeadLease.TenantBreakNotice
            END AS [TenantBreakNotice]
        ...
    ),

    CTE_2 AS
    (
        SELECT
            *    
            ,CASE
                WHEN [TenantBreakNotice] < CONVERT(varchar(10),getdate(),103)  THEN  'Expiry' 
                WHEN [TenantBreakNotice] IS NULL THEN 'Expiry' 
                ELSE 'Break' 
            END AS [LeaseEventType]
        FROM
            CTE_1
    )

SELECT * FROM CTE_2
Run Code Online (Sandbox Code Playgroud)