Sql-Server-2012

SQL Server 2012 - 公用表表達式 (CTE) 返回的行數超出預期

  • March 26, 2020

CTE SQLFiddle

我有一個包含 121 行和 3 列(年齡、男性和女性)的生命表。考慮到性別,我必須獲取所有 121 行。如果性別是“男性”,我從生命表中獲取“男性”列作為 qx,將“女性”列作為 qy,反之亦然。

但是,我需要計算第四列 vx,其值以 1 開頭,後續值計算如下,使用 vx 本身的先前值:

vx = (vx / (1 - @interestRate)^age)

年齡總是從 0 到 120,每一步遞增 1。

對 CTE 不太熟悉,因此,我正在採取嬰兒步驟來使用這種新方法完成我的任務。我需要幫助。

當我嘗試計算 vx 時,查詢返回 7381 而不是 121。

這是我的 CTE:

DECLARE @gender VARCHAR(10) = 'MALE'
DECLARE @interestRate NUMERIC(7, 5) = 0.0354

;WITH cte AS (
   SELECT
       lt.Age,
       CASE
           WHEN @gender = 'MALE' THEN
               lt.Male
           ELSE
               lt.Female
       END AS qx,
       CASE
           WHEN @gender = 'MALE' THEN
               lt.Female
           ELSE
               lt.Male
       END AS qy,
       CAST(1.0 AS NUMERIC(7, 5)) AS vx
   FROM LifeTable AS lt

   UNION ALL

   SELECT
       cte.Age + 1,
       cte.qx,
       cte.qy,
       CAST((vx / (1 + @interestRate)) AS NUMERIC(7, 5)) AS vx
   FROM cte

   WHERE cte.Age < 120

) SELECT COUNT(*) AS NumberOfRows FROM cte OPTION (MAXRECURSION 0);

我有點累,因為我花了一個下午試圖解決這個問題,現在已經是晚上了,所以我的問題可能被認為是低強度的,但我真的需要你的幫助,看看我在哪裡犯了錯誤。

您的問題是 CTE 中的錨點返回所有 120 行而不是單個錨點行。試試這段程式碼,注意 CTE SELECT 中的 WHERE 子句:

DECLARE @gender VARCHAR(10) = 'MALE'
DECLARE @interestRate NUMERIC(7, 5) = 0.0354

;WITH cte AS (
   SELECT
       lt.Age,
       CASE
           WHEN @gender = 'MALE' THEN
               lt.Male
           ELSE
               lt.Female
       END AS qx,
       CASE
           WHEN @gender = 'MALE' THEN
               lt.Female
           ELSE
               lt.Male
       END AS qy,
       CAST(1.0 AS NUMERIC(7, 5)) AS vx
   FROM LifeTable AS lt
   WHERE Age = 1
   UNION ALL

   SELECT
       cte.Age + 1,
       cte.qx,
       cte.qy,
       CAST((vx / (1 + @interestRate)) AS NUMERIC(7, 5)) AS vx
   FROM cte

   WHERE cte.Age < 120

) SELECT COUNT(*) AS NumberOfRows FROM cte OPTION (MAXRECURSION 0);

引用自:https://dba.stackexchange.com/questions/262698