【问题标题】:calculate price in date range in mysql,java在mysql,java中计算日期范围内的价格
【发布时间】:2012-11-26 09:09:45
【问题描述】:

我们有表格,它的数据看起来像

startDate|endDate |price
=========+========+========  
1 dec    | 15 dec | 100  
16 dec   |31 dec  | 200  
1 jan    | 31 Jan | 300  
1 feb    | 10 feb | 30
15 feb   | 28 feb | 40
1 march  | 15 march | 50

价格为一日价。现在我想计算日期之间的价格,比如 12 月 1 日到 12 月 10 日。那么价格将是(100 * 10 天)。另一个条件是计算 12 月 1 日至 1 月 15 日之间的价格,然后价格将为((100 * 15 天)+(200*15 天)+(300*15 天))。还有一个条件是计算 2 月 20 日至 3 月 5 日之间的价格,然后价格将是 (40*8days + 50*5)。如何根据数据价格计算。

【问题讨论】:

  • 你为什么不在计算器上计算?
  • 您需要从数据库中获取日期,然后获取 datediff 并将 datediff(天数)乘以价格。
  • +1 有趣的问题 :)

标签: java mysql


【解决方案1】:

首先,您需要选择任何区间拟合查询日期。然后您可以计算每个间隔的天数和间隔的价格。然后总结一下。

select 
 SUM(
  DATEDIFF(
   if( end_date > '2012-09-12', '2012-09-12', end_date ),
   if( start_date < '2012-09-02', '2012-09-02', start_date )
  ) * price
 )
from prices where start_date < '2012-09-12' and end_date > '2012-09-02'

SqlFiddle - http://sqlfiddle.com/#!2/abc0b/11/0

这是 INT 时间的示例

select 
 SUM(
  DATEDIFF(
   if( end_date > '2012-09-12', '2012-09-12', end_date ),
   if( start_date < '2012-09-02', '2012-09-02', start_date )
  ) * price
 )
from (
 select 
  FROM_UNIXTIME( start_date, '%Y-%m-%d' ) as start_date,
  FROM_UNIXTIME( end_date, '%Y-%m-%d' ) as end_date,
  price
 from prices where start_date <  UNIX_TIMESTAMP( '2012-09-12' ) and end_date >  UNIX_TIMESTAMP( '2012-09-02' )
) as l

编辑:固定示例,感谢小提琴 编辑 2:Unix 时间戳示例

【讨论】:

  • 在表 startDate 和 endDate 中存储为 bigint 值。如果运行您的查询,我会收到以下错误
  • 错误代码:1579 调用本机函数“DATEDIFF”时参数不正确
  • SELECT SUM( DATEDIFF( IF( end_date > UNIX_TIMESTAMP('2012-11-15')*1000, UNIX_TIMESTAMP('2012-11-15')*1000, end_date ), IF( start_date 1355509800352
  • 尝试复制我的示例然后使用它(第二个)
  • 你能把时间戳日期发给我吗?
【解决方案2】:

也许您可以尝试以下方法:

查询:

select price*10
  from prices
  where '2012-09-02' between start_date
  and start_date + interval 10 day

结果:

PRICE*10
1010

参考:*SQLFIDDLE

当前时间间隔只是一个静态值。您可以将其作为动态值传递给您的查询。为了获得涉及的多个日期范围,您只需要在不同的开始日期之间传递不同的间隔来捕捉价格。让我知道是否清楚或您需要进一步澄清:)

【讨论】:

  • 如果第一个间隔是 5 天,第二个是 10 天,第三个是 15 天,会发生什么?
  • @SergeS 你能告诉我错误在哪里吗?它在附加的 SQLFIDDLE 中运行良好。 :) 无论如何,我意识到 OP 的要求比我得到的第一印象要先进得多。我注意到价格的错误。应该是 1010。已修复。
  • 这就是问题所在……这让我很头疼,所以我在两者之间“看到”了错误
【解决方案3】:

编辑:我保留了我的答案,但不再同意,请参阅 cmets 了解原因。

一个可能的答案,虽然我不认为它是最好的(见其他答案)是非规范化你的数据:

day    | price
=======+======
1 dec  | 100
2 dec  | 100
3 dec  | 100
4 dec  | 100
...
15 dec | 100
16 dec | 200
17 dec | 200
...

那么你的答案很简单:

select sum(price) from mytable where day > '1 dec' and day < '15 jan'

这可能会使您的数据更易于使用且更直观,但也有一些缺点:

  • 可能会慢一些;如果范围长时间保持不变,查询多行比 1 行慢
  • 更新速度可能较慢(出于同样的原因)。

【讨论】:

  • 非规范化有点麻烦
  • @SergeS 有没有好文章可以链接我解释原因?听起来您(以及同意的赞成票)对此有强烈的看法。
  • + 重叠可以通过删除 endDate 来解决(并且总是计算它)——这会使选择变得更加困难,但它解决了这个问题。计算成本的查询很快——您为什么这么认为?查询超过 90 行比查询超过 6 行更快?更新一个范围的价格更容易 - 和以前一样 - 更新超过 15 行比更新 1 行更快?
  • 部分答案在我对您的“好处”的回复中......但基本上任何时候您需要选择/更新更多数据时,它都会变慢......标准化会减少数据量
猜你喜欢
  • 1970-01-01
  • 2016-06-10
  • 1970-01-01
  • 1970-01-01
  • 2012-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多