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

时间:2017-04-03 03:26:19

标签: sql postgresql

我有一个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
| ..        |    ..  |     .. |
+-----------+-----------------+

只需要弄清楚如何使用之前的行执行操作。没有兴趣添加到表中。任何帮助表示赞赏:)

**还想指出period_id是有序的,但不一定是递增地增加

2 个答案:

答案 0 :(得分:3)

窗口函数滞后()非常适合。

您可能会注意到我们使用了(amount+0.0)。这样做是为了防止AMOUNTINTNullIf()以避免可怕的除以零

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

答案 1 :(得分:1)

如果您使用的是SQL Server 2012+,请转到John Cappelletti回答。

如果你也不像我这样受祝福,那么下面的代码也适用于你的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

LAG相同。

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