【问题标题】:MySQL to calculate a value against price at the nearest date in another tableMySQL计算另一个表中最近日期的价格值
【发布时间】:2014-05-12 15:13:26
【问题描述】:

我有 2 个表格,我想在其中计算一个值。一张表提供历史的每日价格数据(价格),而第二张表包含包含历史数据和预测数据的年度数据(交易量)。到目前为止,我可以加入这两个表,这样我就可以通过每日对应日期的价格来计算历史年度价值,但不能计算未来的年度价值,我想根据最后的每日价格计算价格表。

当前表结构

Table 1: Prices   (3 fields: date,code,price)
Table 2: Volumes  (3 fields: date,code,units)

当前查询

SELECT v.date,p.price,v.units,CONCAT(p.price*v.units) AS Value
FROM Prices p,Volumes v
WHERE p.code = v.code AND p.date = v.date
AND v.code = 'X' AND (v.date BETWEEN '2012-12-31' AND '2016-12-31')
GROUP BY v.date
ORDER BY v.date
LIMIT 5;

2012-2013 年数据而不是 2012-2016 年的结果:

date   2012-12-31   2013-12-31 
price    50            58
units   100            90
Value  5000           5220

我的年表(成交量)有 2014、2015 和 2016 年的成交量估计(未显示),日表(价格)中的最后一个价格是 65,但上面的查询只会匹配成交量每日价格表中的相应日期值,而不是使用最接近的最后一个值。有人可以建议我如何最好地做到这一点吗?

表格示例(注意:两个表格都使用围绕“日期”和“代码”的复合主键)

音量

date           code    units
2012-12-31     X        100
2012-12-31     Y         50
2013-12-31     X         90
2013-12-31     Y         45
2014-12-31     X         95
2014-12-31     Y         47

价格

date           code    price
2013-12-31     X         50
2013-12-31     Y         25
2014-01-01     X         58
2014-01-01     Y         27
2014-01-02     X         59
2014-01-02     Y         30
-----
2014-03-31     X         48
2014-03-31     Y         26
2014-04-01     X         49
2014-04-01     Y         27
last data point

【问题讨论】:

  • 你能发布一些示例数据或 sql fiddle 吗?而且我不完全确定您的问题是什么……您想要 2012 年至 2016 年之间的“价值”计算是什么?
  • 我不确定您的意思,但是这两个表的日期字段(例如 yyyy-mm-dd)与代码字段(例如 X、Y、Z)和两者都相似其中是每个表中的复合主键。 Volumes 表中的“units”和 Prices 表中的“Price”是整数。
  • 我的意思是你能从你想要的日期范围内发布两个表中的 5-10 行数据吗?
  • 我不认为我可以在这里输入格式化表格,但是每日价格表会有每日历史日期数据(例如'2013-10-15'、2013-10-16'等) 而体积年表,日期数据将是年底的(例如,'2013-12-31'、'2014-12-31'、'2015-12-31'等)。因此,我的上述查询可以选择它们在两个表中匹配的日期,但不能选择未来的年度数据,因为每日价格数据仅包含历史价格值。我需要的是从每日数据中获取最后可用的价格来计算未来的年度价值。
  • 添加的表格示例。希望清楚一点

标签: mysql date select join


【解决方案1】:

如果您希望查询通过将未来预计的单位数量乘以记录的最新价格来获取未来值,那么这就是查询。见工作FIDDLE

SELECT 
  *, 
  (future_units*last_price) as projeted_value --- dont need the CONCAT for this calculation
FROM(
  SELECT 
    v.date, 
    v.units as future_units,
    (SELECT 
       price 
     FROM prices
     ORDER BY date desc --- desc for the most recent
     LIMIT 1) as last_price --- just need the first one
  FROM volumes v
  WHERE v.date > NOW() --- to make it a future date
)as t --- table needs alias

根据 OP 请求更新查询.. 工作 FIDDLE 这个计算与日期相关的价格。一旦你到达未来的日期,它就会用未来的单位计算最后的价格

SELECT
  *,
  if(DATE(the_date) > NOW(), --- if its a future date put in last_price, else put in the current_price
    (future_units*last_price),
    (future_units*current_price))AS value
FROM(
  SELECT
    v.date AS the_date,
    v.units AS future_units,
    v.code,
    p.price AS current_price,
    (SELECT
       price
     FROM prices
     ORDER BY date DESC
     LIMIT 1) AS last_price
  FROM prices p
  LEFT JOIN volumes v ON p.code = v.code
  WHERE p.date >= v.date OR p.date < v.date
  AND DATE(v.date) BETWEEN '2012-12-31' AND '2016-12-31' -- DATE() used to cut out timestamp for accurate comparison
  GROUP BY v.date, v.code, v.units
)AS t

【讨论】:

  • 我想我需要弄清楚这一点,因为我没有立即看到在哪里插入代码项的选择标准(例如选择“代码”)或针对卷的日期选择表(例如日期介于“2012-12-31”和“2016-12-31”之间)。
  • 因此,如果您想要一个未来的日期,那么它将是一个大于今天的日期。这就是为什么我做了WHERE v.date &gt; NOW() 这个查询正在做的是获取最后一个数据点的价格并使用该价格与预计单位相乘
  • 这是一个日期范围在 2012 年和 2016 年之间的样本 sqlfiddle.com/#!2/cc596/17 --- 如果您查看 INSERT INTO 价格.. 最后输入的记录是最新的,价格是 27,这是你要求的 (What I need is to take the last available price from the daily data to use to calculate the future annual values)
  • 好的,我知道你做了什么。您正在根据 p.price(当前价格)的最后价格计算 2012-12-31 至 2016-12-31 年度期间每个 v.unit 的值。我所追求的是通过可用的相应价格(例如 2012-12-31 和 2013-12-31)对 2012-12-31 至 2016-12-31 期间进行估值,但未来使用当前价格期间(例如 2014 年 12 月 31 日至 2016 年 12 月 31 日)。在上面的示例中,这意味着“2013-12-31”将 X 定价为 50,而“2014-12-31”使用的价格将是 49; X 在 '2014-04-01' 的最后可用价格
  • 最好将 ID 添加到此表中,因为如果没有它们,这将更加困难
猜你喜欢
  • 2021-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-26
  • 1970-01-01
  • 1970-01-01
  • 2019-08-16
相关资源
最近更新 更多