SQL:从具有特定值的连续行中减去

时间:2015-06-18 13:10:57

标签: sql postgresql subtraction

我有一张如下表:

+------+-----+------+-------+
|  ID  | day | time | count |
+------+-----+------+-------+
| abc1 |   1 |   12 |     1 |
| abc1 |   1 |   13 |     3 |
| abc1 |   2 |   14 |     2 |
| abc2 |   2 |   18 |     4 |
| abc2 |   2 |   19 |     8 |
| abc2 |   3 |   15 |     3 |
+------+-----+------+-------+

我想要做的是减去" count"如果ID相同,则从下一行开始,该日期与当前行具有相同的值,并且时间大于一个值(例如+1)。 所以我想要的新表有这个布局:

+------+-----+------+-------+------------+
|  ID  | day | time | count | difference |
+------+-----+------+-------+------------+
| abc1 |   1 |   12 |     1 | 2          |
| abc1 |   1 |   13 |     3 | null       |
| abc1 |   2 |   14 |     2 | null       |
| abc2 |   2 |   18 |     4 | 4          |
| abc2 |   2 |   19 |     8 | null       |
| abc2 |   3 |   15 |     3 | null       |
+------+-----+------+-------+------------+

正如您所看到的,只有具有相同ID的行,日期和时间差为1。

2 个答案:

答案 0 :(得分:3)

您可以使用以下使用LEAD窗口函数的查询:

SELECT ID, day, time, count,
       CASE WHEN lTime - time = 1 THEN lCount - count
            ELSE NULL
       END as difference 
FROM (
  SELECT ID, day, time, count,
         LEAD(time) OVER w AS lTime,
         LEAD(count) OVER w AS lCount
  FROM mytable  
  WINDOW w AS (PARTITION BY ID, day ORDER BY time) ) t

上述查询使用相同的窗口两次,以便在同一分区中获取 next 记录的值。外部查询使用这些 next 值来强制执行要求。

Demo here

答案 1 :(得分:0)

在看到您的示例数据和预期输出后,我建议使用左连接,如下所示:

SELECT a.*,
       b.count - a.count
FROM   MyTable a
       LEFT JOIN MyTable b
              ON a.ID = b.ID
                 AND a.time = b.time - 1
                 AND a.count < b.count 

注意:如果有两行或更多行符合连接条件,那么它将显示多行。