【问题标题】:SQL Server - Derived column using its own previous value from the second row onSQL Server - 派生列使用第二行中自己的先前值
【发布时间】:2020-08-20 11:20:40
【问题描述】:

我需要在 SQL Server 中创建一个派生列 ColumnC。规则是 ColumnC 的第一行是 ColumnA 和 ColumnB 的乘积。以下行是ColumnC中上一行的乘积,按年份乘以ColumnA * ColumnC。

+-----------+--------------------------+------------------------+
| **Year**  |        **ColumnA**       |      **ColumnB**       |
+-----------+--------------------------+------------------------+
|  2020     |        0.987441          |        0.001039        |
+-----------+--------------------------+------------------------+
|  2021     |        0.975952          |        0.001117        |
+-----------+--------------------------+------------------------+
|  2022     |        0.965471          |        0.001206        |
+-----------+--------------------------+------------------------+
|  2023     |        0.955950          |        0.001293        |
+-----------+--------------------------+------------------------+
|  2024     |        0.947347          |        0.001387        |
+-----------+--------------------------+------------------------+
|  2025     |        0.939604          |        0.001488        |
+-----------+--------------------------+------------------------+
|  2026     |        0.933461          |        0.001596        |
+-----------+--------------------------+------------------------+
|  2027     |        0.922700          |        0.001710        |
+-----------+--------------------------+------------------------+
|  2028     |        0.914439          |        0.001959        |
+-----------+--------------------------+------------------------+
|  2029     |        0.900277          |        0.002134        |
+-----------+--------------------------+------------------------+

为了保持示例简单,我简化了计算和表格,因此,我需要按照描述计算列。

遵守以下算法对我来说很重要:ColumnC 的第一行是 ColumnA abd ColumnB 的乘积,接下来的行,从第二行开始,使用 ColumnC 的前一行,按 Year × ColumnB × ColumnC 排序。

让我陷入困境的最大问题是我不知道如何获取 ColumnC 的先前值。我不能使用LAG,因为该列还不存在。

SELECT
    ColumnA,
    ColumnB,
    /* First row okay. But the following rows should 
     use the previous value of ColumnC times ColumnA times ColumnB
     that is ColumnC(Year-1) * ColumnA * ColumnB
    CASE WHEN ROW_NUMBER() OVER (ORDER BY Year) = 1 THEN
        ColumnA * ColumnB
    ELSE
        LAG(ColumnC) OVER (ORDER BY Year) * ColumnA * ColumnB
    END AS ColumnC
    */
    (ColumnA * ColumnB) AS ColumnC
FROM TableA

这行不通:

CASE WHEN ROW_NUMBER() OVER (ORDER BY Year ASC) = 1 THEN
    ColumnA * ColumnB
ELSE
    LAG(ColumnC) OVER (ORDER BY Year ASC) * ColumnA * ColumnB
END AS ColumnC

请帮助我理解我的问题。

Useless SQL Fiddle

从ColumnC计算第一行:

从 ColumnC 的第二行开始计算:

结果:

【问题讨论】:

  • 编辑您的问题并显示您想要的结果。
  • 谢谢,戈登!我编辑了问题并在 Google 表格中添加了结果和示例。我也会测试你的解决方案。

标签: sql sql-server


【解决方案1】:

数字变得非常小非常快,但这符合您的描述:

select a.*, 
       columna * columnb,
       exp(sum(log(columna * columnb)) over (order by year))
from tableA a

【讨论】:

  • 嗨,林诺夫先生!谢谢您的回答。我将使用指数实现它的推导。这样就可以了。
【解决方案2】:

根据提供的信息,这是您要查找的内容吗?

DROP TABLE IF EXISTS #TableA

CREATE TABLE #TableA (
    [Year] INT,
    ColumnA DECIMAL(8, 6),
    ColumnB DECIMAL(8, 6)
)

INSERT INTO #TableA (
  [Year],
  ColumnA,
  ColumnB
)
VALUES
    (2020, 0.987441, 0.001039),
    (2021, 0.975952, 0.001117),
    (2022, 0.965471, 0.001206),
    (2023, 0.955950, 0.001293),
    (2024, 0.947347, 0.001387),
    (2025, 0.939604, 0.001488),
    (2026, 0.933461, 0.001596),
    (2027, 0.922700, 0.001710),
    (2028, 0.914439, 0.001959),
    (2029, 0.900277, 0.002134);

    SELECT *, CASE WHEN ROW_NUMBER() OVER (ORDER BY Year ASC) = 1 THEN ColumnA * ColumnB
              ELSE LAG(ColumnB) OVER (ORDER BY Year ASC) * ColumnA * ColumnB
               END AS ColumnC
      FROM #TableA

【讨论】:

  • 哇!感谢您的快速回答,但我认为 Linoff 先生关于指数的思想将更有效地帮助我。
猜你喜欢
  • 2021-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-09
  • 2014-08-02
  • 1970-01-01
  • 2017-04-30
相关资源
最近更新 更多