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

时间:2017-08-15 11:28:06

标签: sql-server tsql

我有很长的custom查询,但我已在此处粘贴相关部分。

我需要使用SELECT语句的结果在另一个CASE语句中使用。我在SQL Server中这样做。

非常感谢您的帮助。

CASE

4 个答案:

答案 0 :(得分:3)

您不能在定义它的同一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);

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

答案 1 :(得分: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

答案 2 :(得分:2)

正如@Juergen指出的那样,你无法完全按照自己的意愿行事,但是你可以在子查询中计算第一个CASE表达式,然后将它用作外包装查询:

WITH cte AS (
    SELECT
        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]
    FROM HeadLease
)

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

答案 3 :(得分:1)

您可以使用派生表/子查询将第一个{ "@timestamp" => 2017-08-15T09:30:17.000Z, "flightSearchRequest" => { "action" => "processed", "sessionId" => "a216925---ff5992be7520924ff25992be75209c7", "time" => 1502789417, "page" => "order", "type" => "bookingProcess" }, "level" => "INFO", "module" => "api", "@version" => "1", "message" => "[2017-08-15 12:30:17] api.INFO: {\"sessionId\":\"a216925---ff5992be7520924ff25992be75209c7\",\"action\":\"processed\",\"time\":1502789417,\"type\":\"bookingProcess\",\"page\":\"order\"} [] []", "timestamp" => "2017-08-15 12:30:17" } 表达式移动到case中,如下所示:

from

注意:

  • 不要将字符串作为日期进行比较,这会导致问题;特别是你指定的风格(select cc.Name as CompanyName , convert(varchar(10),hl.[TenantBreakNotice],103) as TenantBreakNotice , case when hl.[TenantBreakNotice] < getdate() then 'Expiry' when hl.[TenantBreakNotice] is null then 'Expiry' else 'Break' end as [LeaseEventType] from ( select *, case when substring(HeadLease.TenantBreakNotice,len(HeadLease.TenantBreakNotice),1) = 'M' then dateadd(day,-365/(12/substring(HeadLease.TenantBreakNotice,1,len(HeadLease.TenantBreakNotice)-1)),HeadLease.TenantBreakDate) when substring(HeadLease.TenantBreakNotice,len(HeadLease.TenantBreakNotice),1) = 'Y' then dateadd(day,-365*(substring(HeadLease.TenantBreakNotice,1,len(HeadLease.TenantBreakNotice)-1)),HeadLease.TenantBreakDate) else HeadLease.TenantBreakNotice end as [TenantBreakNotice] from HeadLease ) as hl inner join CompanyContact cc on cc.... )。
  • Bad Habits to Kick : Using shorthand with date/time operations - Aaron Bertrand
  • Bad habits to kick : mis-handling date / range queries - Aaron Bertrand