【问题标题】:SQL - Same Table join to calculate profit from last entrySQL - 同表连接以计算最后一个条目的利润
【发布时间】:2016-12-22 11:11:29
【问题描述】:

我有一张各种产品的交易表。我想计算每个人的利润

Product                Date           Profit     Incremental Profit
--------------------- --------------------------- -----------
Apple                 2016-05-21      100
Banana                2016-05-21      60
Apple                 2016-06-15      30
Apple                 2016-08-20      10
Banana                2016-08-20      5

我能否创建一个 SQL 查询,该查询可以基于产品进行分组,并在每个日期为每个产品提供增量利润。例如,在 2015 年 5 月 21 日,因为这是第一次约会,所以增量利润将为 0。但在 2016 年 6 月 15 日,它将是 -70 (30-100)。

预期的输出是:

Product                Date           Profit     Incremental Profit
    --------------------- --------------------------- -----------
    Apple                 2016-05-21      100    0
    Banana                2016-05-21      60     0
    Apple                 2016-06-15      30     -70
    Apple                 2016-08-20      10     -20
    Banana                2016-08-20      5      -55

【问题讨论】:

  • 也添加预期的结果。 (复制、粘贴和调整!)
  • 行是否总是按数据排序?我的意思是我可以只取最后一个条目,而不是按日期查找最后一个条目吗?
  • @jarlh 我已经添加了预期的输出表。
  • @JanWalczak 这些行需要排序,因为增量利润将基于两个连续日期之间的利润差异。
  • 请问您的记录是否添加了排序日期。表中较早的日期总是较高?

标签: sql .net sql-server database sql-server-2008


【解决方案1】:

试试这个

DECLARE @Tbl TABLE (Product NVARCHAR(50), Date_ DATETIME, Profit INT)
INSERT INTO @Tbl
VALUES
('Apple'  ,               '2016-05-21',      100),
('Banana',            '2016-05-21',      60 ),
('Apple',             '2016-06-15',      30 ),
('Apple',             '2016-08-20',      10 ),
('Banana',            '2016-08-20',      5  )


;WITH CTE
AS
(   
    SELECT
        *,
        ROW_NUMBER() OVER (PARTITION BY Product ORDER BY Date_) RowId
    FROM @Tbl

)


SELECT 
    CurrentRow.Product ,
    CurrentRow.Date_ ,
    CurrentRow.Profit ,
    CurrentRow.Profit - ISNULL(PrevRow.Profit, CurrentRow.Profit) 'Incremental Profit'
FROM 
    CTE CurrentRow LEFT JOIN 
    (SELECT CTE.Product ,CTE.Profit, CTE.RowId + 1 RowId FROM CTE) PrevRow ON CurrentRow.Product = PrevRow.product AND
                                                                              CurrentRow.RowId = PrevRow.RowId
ORDER BY CurrentRow.Date_

结果:

Product     Date_       Profit  Incremental Profit
Apple       2016-05-21  100     0
Banana      2016-05-21  60      0
Apple       2016-06-15  30      -70
Apple       2016-08-20  10      -20
Banana      2016-08-20  5       -55

编辑:

UPDATE @Tbl
SET [Incremental Profit] = A.[Incremental Profit]
FROM
(
    SELECT 
        CurrentRow.Product ,
        CurrentRow.Date_ ,
        CurrentRow.Profit ,
        CurrentRow.Profit - ISNULL(PrevRow.Profit, CurrentRow.Profit) 'Incremental Profit'
    FROM 
        (SELECT *, ROW_NUMBER() OVER (PARTITION BY Product ORDER BY Date_) RowId FROM @Tbl) CurrentRow LEFT JOIN 
        (SELECT *, ROW_NUMBER() OVER (PARTITION BY Product ORDER BY Date_) + 1 RowId FROM @Tbl) PrevRow ON CurrentRow.Product = PrevRow.Product AND
                                                                                                           CurrentRow.RowId = PrevRow.RowId
) A
WHERE
    [@Tbl].Product = A.Product AND
    [@Tbl].Date_ = A.Date_

【讨论】:

  • 感谢您的解决方案。这行得通。是否可以将其更新到现有表中,而不是在此处进行选择。
  • @Swati 是的,用你的桌子改变@Tbl
  • 是的,我确实更改了表格,但如何更新记录。我认为更新语法必须在查询中。所以假设 Tbl 有一个列“IncrementalProfit”,那么这个查询的变化是什么。抱歉,但我是 SQL 新手,您的解决方案有点复杂 :)
  • 答案已更新。将@Tbl 更改为your existing table
【解决方案2】:

也许你可以使用它。

select 
    a.product
    ,a.date
    ,a.profit
    ,isnull(a.profit - (select top 1 x.profit from profit x where x.product = a.product and x.date < a.date),0) as profit
from PROFIT a
order by product, date

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-10
    • 2021-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多