SQL:根据两个不同的日期减去同一列中的值

问题描述 投票:0回答:2

我有一个如下表,我想根据不同的日期减去“价格”列中的值。减去它们后,我打算只使用第一组日期时间

减法前的表格

数据类型 日期时间 价格
价格_1_2_点差 2023-10-01 96.06
价格_1_2_点差 2023-10-02 112.82
价格_1_2_点差 2023-11-01 105.72
价格_1_2_点差 2023-11-02 130.04

根据同一天但不同月份减去价格

  1. 2023-10-01 和 2023-11-01 = 96.06 - 105.72 = -9.66

  2. 2023-10-02 和 2023-11-02 = 112.82 - 130.04 = -17.22

减去后的表格(预期输出)

数据类型 日期时间 价格
价格_1_2_点差 2023-10-01 -9.66
价格_1_2_点差 2023-10-02 -17.22

尝试过使用这个

CASE WHEN DataType = 'Price_1_2_spread' THEN ROUND(IF(Datetime BETWEEN '2023-10-01' AND '2023-10-02',Price,NULL) - IF(Datetime BETWEEN '2023-11-01' AND '2023-11-02',Price,NULL),2)
ELSE NULL
END AS Price

但这没有用。

感谢您的帮助!

sql case
2个回答
0
投票

我相信您可能想使用 LEAD 窗口函数 从具有相同

Price
 月中某日 
的“下一个”行获取 DataType

LEAD(Price) OVER (PARTITION BY DataType, EXTRACT(DAY FROM Datetime) ORDER BY Datetime)

这是使用 Oracle 19c 的可能解决方案:

  WITH prices AS
(
    SELECT 'Price_1_2_spread' AS DataType, DATE '2023-10-01' AS Datetime, 96.06 AS Price FROM dual UNION ALL
    SELECT 'Price_1_2_spread' AS DataType, DATE '2023-10-02' AS Datetime, 112.82 AS Price FROM dual UNION ALL
    SELECT 'Price_1_2_spread' AS DataType, DATE '2023-11-01' AS Datetime, 105.72 AS Price FROM dual UNION ALL
    SELECT 'Price_1_2_spread' AS DataType, DATE '2023-11-02' AS Datetime, 130.04 AS Price FROM dual
),
subtracted AS (
    SELECT DataType, Datetime,
        Price - LEAD(Price) OVER (PARTITION BY DataType, EXTRACT(DAY FROM Datetime) ORDER BY Datetime) AS Price
    FROM prices
)
SELECT DataType, Datetime, Price
FROM subtracted
WHERE Price IS NOT NULL
ORDER BY DataType, Datetime;

它返回以下输出:

数据类型 日期时间 价格
价格_1_2_点差 2023-10-01 -9.66
价格_1_2_点差 2023-10-02 -17.22

0
投票

您将需要选择所需的任何行并将它们与要减去的行连接起来。 LEFT JOIN 包括来自 selectMonth 的行,其中没有匹配的 subtractMonth,当您尝试减去时,这将导致 NULL。 INNER JOIN 会过滤掉这些。

SELECT selectMonth.DataType, selectMonth.Datetime, selectMonth.Price - subtractMonth.Price AS PriceDifference
FROM tablePriceSpread AS selectMonth
LEFT JOIN tablePriceSpread AS subtractMonth ON selectMonth.DataType = subtractMonth.DataType AND selectMonth.Datetime = DATEADD(MONTH, -1, subtractMonth.Datetime)
WHERE selectMonth.DataType = 'Price_1_2_spread'

这里有一些额外的注意事项。

  1. 上个月的同一天并不总是匹配(月份的天数不同),因此您可能需要考虑如何处理此问题。在示例中,DATEADD 将多次匹配该月的最后一天。
  2. 您可能会考虑将列命名为“Datetime”以外的名称,因为这已经是可能的数据类型,也是保留字。
© www.soinside.com 2019 - 2024. All rights reserved.