【问题标题】:SQL: Subtract from consecutive rows with specific valueSQL:从具有特定值的连续行中减去
【发布时间】:2015-09-04 03:31:52
【问题描述】:

我有一张如下表:

+------+-----+------+-------+
|  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 |
+------+-----+------+-------+

如果 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 的行。

【问题讨论】:

    标签: sql postgresql subtraction


    【解决方案1】:

    您可以使用以下利用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 值来执行要求。

    Demo here

    【讨论】:

    • 非常感谢!这个查询似乎工作正常。我有什么办法可以加快速度。现在,100 行 LIMIT(从 150 万行)需要 28 秒。
    • @user1798707 我想不出任何方法来简化这个查询。您是否在 IDdaytime 列上放置了索引?
    • 是的,我有。这是一个更大查询的一部分,所以当我合并它时,时间大大减少了。现在只需 1 秒。非常感谢。还有一点我想问的。我可以排除差异列中具有 NULL 的行吗?将输出显示为 NULL 是我的错。再次感谢您。
    • @user1798707 这很容易。只需添加WHERE lCount IS NOT NULL。见here
    【解决方案2】:

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

    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 
    

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

    【讨论】:

      猜你喜欢
      • 2021-10-03
      • 1970-01-01
      • 1970-01-01
      • 2020-09-24
      • 2015-07-27
      • 1970-01-01
      • 2013-10-31
      • 2018-06-05
      • 1970-01-01
      相关资源
      最近更新 更多