0

大家下午好,

我编写了一个存储过程,因为它可以工作并且执行速度相对较快,因为它只是进行相当简单的计算。我想你可以说我对过程本身的问题是 SELECT 和 ORDER BY 子句中重复的“CASE 语句”的数量。我的 TSQL 知识仍然相当 N00bish,因为我充其量仍然是一个“P”板。是否可以进一步简化我的代码,以便我只有 CASE WHEN 计算出现一次,并且我可以继续在多个地方使用它?我相信这对于将来的校对会更好,而且我只需要在根语句处进行更改,而不必在多个位置进行更改!

@Officer_Name 是从用户界面传入的变量。如您所见,F_YEAR(财政年度)、F_Quarter(财政季度)字段计算在语句的 Order By 部分再次重复,我想知道是否可以避免这种情况:) 非常感谢您提前拯救了这个 damoiseau苦恼中,我希望有一个慷慨的 TSQL 水平更高的专家可以帮我这个忙!非常感激。

    BEGIN

    SELECT  TOP (100) PERCENT 
    COUNT(DISTINCT(dbo.TableA.[Account ID])) AS Applications,
    SUM(CASE WHEN [Client Claims] LIKE '%claim%' THEN 1 ELSE 0 END) AS Main_Client,
    COUNT([TableA_ID]) AS Clients,
    (CASE
    WHEN [Finalised date] < '07/01/' +  CONVERT(VARCHAR(4), DATEPART(Year,GETDATE()) - 2) THEN 'PAST CASES'
    WHEN [Finalised date] BETWEEN '07/01/' +  CONVERT(VARCHAR(4), DATEPART(Year,GETDATE()) - 2)  AND '06/30/' +  CONVERT(VARCHAR(4), DATEPART(Year,GETDATE()) - 1) THEN 'YEAR'
    WHEN MONTH([Finalised date]) BETWEEN 1  AND 3  THEN ' Q3'
    WHEN MONTH([Finalised date]) BETWEEN 4  AND 6  THEN ' Q4'
    WHEN MONTH([Finalised date]) BETWEEN 7  AND 9  THEN ' Q1'
    WHEN MONTH([Finalised date]) BETWEEN 10 AND 12 THEN ' Q2'
    END) AS F_Quarter, 
    (CASE 
    WHEN [Finalised date] < '07/01/' +  CONVERT(VARCHAR(4), DATEPART(Year,GETDATE()) - 2) THEN CONVERT(VARCHAR(4), DATEPART(Year,GETDATE()) - 2) + ' & Older'
    WHEN MONTH([Finalised date]) BETWEEN 1  AND 6 THEN convert(char(4), YEAR([Finalised date]) - 0)
    WHEN MONTH([Finalised date]) BETWEEN 7  AND 12 THEN convert(char(4), YEAR([Finalised date]) + 1) 
    ELSE convert(char(4), YEAR([Finalised date])) 
    END) AS F_YEAR

FROM    dbo.TableB INNER JOIN
        dbo.TableA ON dbo.TableB.[Account ID] = dbo.TableA.[Account ID] LEFT OUTER JOIN
        dbo.Officers ON dbo.TableA.[Account Officer] = dbo.Officers.FullName

WHERE   [Case Officer] = @Officer_Name AND [Finalisation] IS NOT NULL

GROUP BY 
    (CASE 
    WHEN [Finalised date] < '07/01/' +  CONVERT(VARCHAR(4), DATEPART(Year,GETDATE()) - 2) THEN CONVERT(VARCHAR(4), DATEPART(Year,GETDATE()) - 2) + ' & Older'
    WHEN MONTH([Finalised date]) BETWEEN 1  AND 6 THEN convert(char(4), YEAR([Finalised date]) - 0)
    WHEN MONTH([Finalised date]) BETWEEN 7  AND 12 THEN convert(char(4), YEAR([Finalised date]) + 1) 
    ELSE convert(char(4), YEAR([Finalised date])) 
    END),
    (CASE
    WHEN [Finalised date] < '07/01/' +  CONVERT(VARCHAR(4), DATEPART(Year,GETDATE()) - 2) THEN 'PAST CASES'
    WHEN [Finalised date] BETWEEN '07/01/' +  CONVERT(VARCHAR(4), DATEPART(Year,GETDATE()) - 2)  AND '06/30/' +  CONVERT(VARCHAR(4), DATEPART(Year,GETDATE()) - 1) THEN 'YEAR'
    WHEN MONTH([Finalised date]) BETWEEN 1  AND 3  THEN ' Q3'
    WHEN MONTH([Finalised date]) BETWEEN 4  AND 6  THEN ' Q4'
    WHEN MONTH([Finalised date]) BETWEEN 7  AND 9  THEN ' Q1'
    WHEN MONTH([Finalised date]) BETWEEN 10 AND 12 THEN ' Q2'
    END)

ORDER BY F_YEAR DESC, F_Quarter
END
4

1 回答 1

0

您可以将 CASE 表达式放在 CTE 中,并在后面的查询中通过其别名多次引用它。但是,由于您的 CASE 表达式与 forF_YEAR不同,F_Quarter因此无法对整个查询仅使用一个 CASE 表达式。在伪代码中,您可以这样做:

WITH cte AS (
   SELECT ...
   , {CASE Expression for year} AS F_Year
   , {CASE Expression for quarter} AS F_Quarter
   FROM...
)
SELECT ... F_Year, F_Quarter
FROM ... WHERE ...
GROUP BY F_Year, F_Quarter ...
于 2019-08-09T17:55:08.113 回答