【问题标题】:Subtracting two values in a column using sql使用sql减去列中的两个值
【发布时间】:2016-05-08 18:15:09
【问题描述】:

我想使用 SQL 查询显示两个不同行中两个值的减法。

这是表结构:

id | Value|
-----------
1  | 20 | 
2  | 30 | 
3  | 50 |
4  | 70 |
5  | 100 |

输出应该如下。

id | Value| Difference |
------------------------
1  | 20 | Null |
2  | 30 | 10 |
3  | 50 | 20 |
4  | 70 | 20 |
5  | 100 | 30 |

【问题讨论】:

  • 你保证ID字段代表一个连续的数字序列吗?前一行的ID 是否总是比当前行少一个

标签: mysql sql-server-2008-r2 oracle10g


【解决方案1】:

我有一个SQL Server 的解决方案,我希望 Oracle 和 MySQL 的解决方案非常相似。

注意: Ids 不必是连续的,但我使用它们对结果进行排序。

设置:

-- drop table dbo.testVals
CREATE TABLE dbo.testVals (
    Id INT,
    Value INT
)
GO

-- truncate table dbo.testVals 
INSERT INTO dbo.testVals (Id, Value)
VALUES (1, 20),  (2, 30),  (3, 50), (4, 70), (5, 100)
GO

SQL Server 2008 R2 解决方案:

;WITH cte as (
    SELECT Id, Value, ROW_NUMBER() OVER (ORDER BY Id) AS RowNo
    FROM dbo.testVals
)
SELECT r1.Id, r1.Value, r1.Value - r2.Value 
FROM cte r1 
    LEFT JOIN cte r2 ON r2.RowNo = r1.RowNo - 1
GO

SQL Server 2012 解决方案:(我们有 LAG 和 LEAD 函数)

SELECT Id, Value, Value - LAG(Value, 1, NULL) OVER (ORDER BY Id)
FROM dbo.testVals
GO

Oracle 具有 LAG 和 LEAD 函数。 MySQL 会 not seem to have 他们,所以你应该使用类似于第一个查询的东西。

【讨论】:

    【解决方案2】:

    试试这个:

    SELECT t1.id, t1.value,
    CASE t2.value WHEN NULL THEN NULL ELSE (t1.value - t2.value) END AS Difference
    FROM mytable t1 LEFT JOIN mytable t2 ON t1.id = (t2.id + 1) ORDER BY t1.id
    

    sqlfiddle

    【讨论】:

    • ID 有空档怎么办?在 5 之后说 7?
    【解决方案3】:

    另一种方法

    SELECT id, VALUE, (VALUE - previousValue) AS difference  FROM (
    SELECT id, VALUE, @prevValue previousValue , @prevValue := `VALUE` FROM `mytable`
    JOIN (SELECT @prevValue := NULL) a
    ORDER BY id ) b;
    

    Fiddle

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-22
      • 1970-01-01
      • 2021-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多