我正在尝试提供公式 ([CALCULATION]) 的总体结果,然后在两个额外的列 ([NO_TENURE] & [TENURE]) 中进行相同的计算,但使用“CASE WHEN”根据另一列过滤信息称为 [TENURE],所有内容都在一行中,如下所示:
MONTH TYPE CALCULATION NO_TENURE TENURE
----------- ---------- --------------------------------------- --------------------------------------- ---------------------------------------
1 TYPE1 5.33333333333 5.33333333333 6.81333333333
现在是这样显示的:
MONTH TYPE CALCULATION NO_TENURE TENURE
----------- ---------- --------------------------------------- --------------------------------------- ---------------------------------------
1 TYPE1 5.33333333333 5.33333333333 NULL
1 TYPE1 6.81333333333 NULL 6.81333333333
1 TYPE2 5.55555555555 5.55555555555 NULL
1 TYPE2 5.95238095238 NULL 5.95238095238
这是我使用的代码:
IF OBJECT_ID('TEMPDB..#TEST') IS NOT NULL DROP TABLE #TEST
GO
CREATE TABLE #TEST
(
MONTH INT,
TYPE VARCHAR(10),
TENURE INT,
NUMERADOR INT,
DENOMINADOR INT
)
INSERT INTO #TEST
VALUES (1, 'TYPE1', 35, 320, 60),
(1, 'TYPE1', 96, 511, 75),
(1, 'TYPE2', 23, 400, 72),
(1, 'TYPE2', 102, 500, 84);
SELECT MONTH
,TYPE
,(SUM(NUMERADOR)/CONVERT(DECIMAL(10,4) ,SUM(DENOMINADOR))) [CALCULATION]
,CASE WHEN TENURE < 90 THEN (SUM(NUMERADOR)/CONVERT(DECIMAL(10,4) ,SUM(DENOMINADOR))) END [NO_TENURE]
,CASE WHEN TENURE >= 90 THEN (SUM(NUMERADOR)/CONVERT(DECIMAL(10,4) ,SUM(DENOMINADOR))) END [TENURE]
FROM #TEST
GROUP BY MONTH,
TYPE,
TENURE
非常感谢您的帮助!
您的 GROUP BY 中有 TENURE,这意味着源数据中的每个不同任期将在输出中得到不同的行。
如果你从那里拿走 TENURE,你会得到你想要的一排。您的 CASE 表达式将不起作用,因为它应该在聚合函数内部...
SELECT
MONTH
,TYPE
,SUM( NUMERADOR ) / CONVERT(DECIMAL(10,4), SUM( DENOMINADOR )) [CALCULATION]
,SUM(CASE WHEN TENURE < 90 THEN NUMERADOR END) / CONVERT(DECIMAL(10,4), SUM(CASE WHEN TENURE < 90 THEN DENOMINADOR END)) [NO_TENURE]
,SUM(CASE WHEN TENURE >= 90 THEN NUMERADOR END) / CONVERT(DECIMAL(10,4), SUM(CASE WHEN TENURE >= 90 THEN DENOMINADOR END)) [TENURE]
FROM
#TEST
GROUP BY
MONTH,
TYPE
下一个问题是如何避免大量重复。这是通过使用子查询、CTE 或应用函数在一个范围内定义表达式并在不同范围内使用它们来完成的。
WITH
NORMALISED_RESULT AS
(
SELECT
MONTH,
TYPE,
IS_TENURED,
SUM(NUMERADOR) / CONVERT(DECIMAL(10,4), SUM(DENOMINADOR)) AS CALCULATION
FROM
#TEST
CROSS APPLY
(
SELECT
CASE WHEN TENURE < 90 THEN 0
WHEN TENURE >= 90 THEN 1
ELSE -1 END AS IS_TENURED
)
AS TENURE_CHECK
GROUP BY
GROUPING SETS(
(MONTH, TYPE, IS_TENURED),
(MONTH, TYPE)
)
)
-- This next part just pivots the normalised results
-- It can be skipped if three rows of normalised results is acceptable.
SELECT
MONTH,
TYPE,
MAX(CASE WHEN IS_TENURED IS NULL THEN CALCULATION END) AS CALCULATION,
MAX(CASE WHEN IS_TENURED = 0 THEN CALCULATION END) AS NO_TENURE,
MAX(CASE WHEN IS_TENURED = 1 THEN CALCULATION END) AS TENURE
FROM
NORMALISED_RESULT
GROUP BY
MONTH,
TYPE
ELSE -1
仅在某些行有 NULL
的情况下才存在 TENURE
.
演示:db<>fiddle