TSQL:尝试 Streamline/Optimise 我的存储过程
TSQL: Trying to Streamline/Optimise my Stored-Procedure
大家下午好,
我写了一个存储过程,因为它只做相当简单的计算,所以工作和执行速度相对较快。我想您可能会说我对程序本身的问题是 SELECT 和 ORDER BY 子句中重复 'CASE Statement' 的次数。我的 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
您可以将 CASE 表达式放在 CTE 中,并在后面的查询中通过别名多次引用它。但是,由于 F_YEAR
的 CASE 表达式不同于 F_Quarter
的 CASE 表达式,因此无法对整个查询只使用一个 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 ...
大家下午好,
我写了一个存储过程,因为它只做相当简单的计算,所以工作和执行速度相对较快。我想您可能会说我对程序本身的问题是 SELECT 和 ORDER BY 子句中重复 'CASE Statement' 的次数。我的 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
您可以将 CASE 表达式放在 CTE 中,并在后面的查询中通过别名多次引用它。但是,由于 F_YEAR
的 CASE 表达式不同于 F_Quarter
的 CASE 表达式,因此无法对整个查询只使用一个 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 ...