在sql中添加额外列以显示与上一行的比率

在sql中添加额外列以显示与上一行的比率,sql,postgresql,Sql,Postgresql,我有一个SQL表,其格式如下: SELECT period_id, amount FROM table; +--------------------+ | period_id | amount | +-----------+--------+ | 1 | 12 | | 2 | 11 | | 3 | 15 | | 4 | 20 | | .. | .. | +-----------+

我有一个SQL表,其格式如下:

SELECT period_id, amount FROM table;
+--------------------+
| period_id | amount |
+-----------+--------+
| 1         |    12  |
| 2         |    11  |
| 3         |    15  |
| 4         |    20  |
| ..        |    ..  |
+-----------+--------+
我想添加一个额外的列(仅在我的select语句中),用前面的金额计算增长率,如下所示:

SELECT period_id, amount, [insert formula here] AS growth FROM table;
+-----------------------------+
| period_id | amount | growth |
+-----------+-----------------+
| 1         |    12  |        |
| 2         |    11  |   0.91 |  <-- 11/12
| 3         |    15  |   1.36 |  <-- 15/11
| 4         |    20  |   1.33 |  <-- 20/15
| ..        |    ..  |     .. |
+-----------+-----------------+
从表中选择期间id、金额、[在此插入公式]作为增长;
+-----------------------------+
|期间|金额|增长|
+-----------+-----------------+
| 1         |    12  |        |

|2 | 11 | 0.91 |窗口函数Lag()

您可能会注意到,我们使用
(金额+0.0)
。如果
AMOUNT
是一个
INT
,并且
NullIf()
避免可怕的被零除,就可以这样做

Declare @YourTable table (period_id int,amount int)
Insert Into @YourTable values
( 1,12),
( 2,11),
( 3,15),
( 4,20)


Select period_id
      ,amount
      ,growth  = cast((amount+0.0) / NullIf(lag(amount,1) over (Order By Period_ID),0) as decimal(10,2))
 From  @YourTable
返回

period_id   amount  growth
1           12      NULL
2           11      0.92
3           15      1.36
4           20      1.33

如果您使用的是SQL Server 2012+,请选择答案

如果你也不像我那么幸运,那么下面的代码在2008年版本中也适用于你

Declare @YourTable table (period_id int,amount int)
Insert Into @YourTable values
( 1,12),
( 2,11),
( 3,15),
( 4,20)

;WITH CTE AS (
    SELECT ROW_NUMBER() OVER (
            ORDER BY period_id
            ) SNO
        ,period_id
        ,amount
    FROM @YourTable
    )
SELECT C1.period_id
    ,C1.amount
    ,CASE 
        WHEN C2.amount IS NOT NULL AND C2.amount<>0
            THEN CAST(C1.amount / CAST(C2.amount AS FLOAT) AS DECIMAL(18, 2))
        END AS growth
FROM CTE C1
LEFT JOIN CTE C2 ON C1.SNO = C2.SNO + 1

在哪里关闭强制转换和NullIf括号?@jordanc就在“之前”作为十进制(10,2)@jordanc NullIf(…,0),因此如果表达式…为零,则返回null,否则…expressionoops-postgres..我将删除标记,它们似乎已经添加了自己
+-----------+--------+--------+
| period_id | amount | growth |
+-----------+--------+--------+
|         1 |     12 | NULL   |
|         2 |     11 | 0.92   |
|         3 |     15 | 1.36   |
|         4 |     20 | 1.33   |
+-----------+--------+--------+