【问题标题】:mysql SELECT DATEDIFF from rate ranges and get pricemysql 从速率范围中选择 DATEDIFF 并获取价格
【发布时间】:2022-01-11 00:25:51
【问题描述】:

如果有人在 2/3/22 入住并在 2/6/2022 退房,我正在尝试获得总房价。有些天属于不同​​的费率范围,您将在下面看到我能够获得每个范围内的天数,但我需要总价。任何帮助都会很棒。 所以例如 267+267+281 = 815

数据

Unit fromdate todate day
motel5 2022-01-10 2022-02-04 281
motel5 2022-02-05 2022-03-04 267

查询

SELECT unit, fromdate, todate, day, 
(DATEDIFF( IF (todate > '2022-02-06' , '2022-02-06', todate), 
IF ( fromdate < '2022-02-02' , '2022-02-02' , fromdate )) ) 
AS days FROM rates_new WHERE fromdate <= '2022-02-06' 
AND todate > '2022-02-02' AND Unit = 'motel5'
ORDER BY days ASC

结果

Unit fromdate todate day days
motel5 2022-01-10 2022-02-04 281 2
motel5 2022-02-05 2022-03-25 267 1

【问题讨论】:

  • 您当前的查询将返回 281 = 2 天 .. 和 267 = 1 天。所以实际上是281+281+267=829
  • 如果一个人在 2/3/22 入住并在 2/6/2022 退房包含的天数应该是 3、4、5,但根据您的结果,好像是4,5,6,你是指包含退房日期,但不包括入住日期,请问MySQL版本是多少。
  • @FanoFN 问题是我们如何获得代码来给我们 829?
  • @ProGu 我只是想弄清楚如何让这段代码给我总价
  • @LynnRoss ,根据您当前的数据样本和您的情况,正确的结果是什么?我在之前的评论中提到,您当前的查询返回的是281+281+267=829,而不是您声称的267+267+281=815。所以,我的意思是你的查询是错误的,或者你的预期结果是错误的。请澄清,谢谢

标签: mysql database datediff


【解决方案1】:

我认为您可以将查询修改为以下内容:

SET @mindt := '2022-02-02';
SET @maxdt := '2022-02-06';

SELECT unit,
       SUM(days*day)
       FROM
(SELECT unit, fromdate, todate, day,
        DATEDIFF(IF(todate > @maxdt, @maxdt, todate), 
                  IF(fromdate < @mindt, @mindt, fromdate)) AS days
  FROM rates_new 
  WHERE fromdate <= '2022-02-06' 
  AND todate > '2022-02-02') V
GROUP BY unit;

不要在查询中定义日期,而是尝试使用变量,这样您只需更改变量的日期值并将变量相应地放置在查询中。然后去掉这个条件:

AND Unit = 'motel5'

并将查询转换为子查询。从那里你可以计算SUM(days*day),然后按unit分组。

Updated fiddle

【讨论】:

  • @FanFN 如果插入以下费率然后尝试您的代码出现问题,您能帮忙吗? ('motel5', '2022-01-10', '2022-02-04', 273), ('motel5', '2022-02-05', '2022-04-01', 324), (' motel5', '2022-04-02', '2022-04-08', 310), ('motel5', '2022-04-09', '2022-04-22', 559), ('motel5' , '2022-04-23', '2022-04-29', 437), ('motel5', '2022-04-30', '2022-05-06', 466), ('motel5', ' 2022-05-07', '2022-05-13', 557), ('motel5', '2022-05-14', '2022-05-20', 613), ('motel5', '2022- 05-21', '2022-06-03', 634), ('motel5', '2022-06-04', '2022-06-10', 659), ('motel5', '2022-06- 11', '2022-06-17', 717);
  • 这取决于,但如果您当前的问题已被此处发布的任何答案解决,您应该接受一个答案并将其视为已解决。任何后续问题都应作为单独的问题发布。我了解到"chameleon questions" 非常气馁。
  • 我明白了,DATEDIFF() 部分实际上与您的原始查询相同,所以我只是重新使用它,但用变量替换了定义的日期。一目了然,我可以看到放在IF() 中的条件是导致结果错误的原因。让我看看我能做什么
  • 对不起@LynnRoss,看来WHERE fromdate &lt;= '2022-02-06' AND todate &gt; '2022-02-02'毕竟是必要的。我用新的查询和小提琴编辑了我的答案。
【解决方案2】:

您可以使用least() 和greatest() 获取范围或访问结束日期之间的范围内的有效边界。使用datediff()获取当天的差价,乘以价格并使用sum()聚合得到访问总价。

SELECT sum(datediff(least(adddate('2022-02-06',
                                  INTERVAL 1 DAY),
                          todate),
                    greatest('2022-02-03',
                             fromdate))
           * day)
       FROM rates_new
       WHERE unit = 'motel5'
             AND fromdate <= '2022-02-06'
             AND todate >= '2022-02-03';

db<>fiddle

【讨论】:

  • 总价应该是829,不是815,不知道为什么要815
  • @LynnRoss:你写了 815 作为想要的结果!
  • 所以说我们在范围内添加了另一个 hotal,比如说 motel 6,我们怎么才能得到两者的总数?
  • @LynnRoss:同样的入住和退房?使用unit IN ('motel5', 'motel6') 而不是unit = 'motel5'。但这并不能解决关于哪个和是正确的谜题,815 还是 829...
  • @LynnRoss:将有关单位的条件完全排除在WHERE 子句之外,并添加一个GROUP BY unit 子句。但是请停止扩展原始问题。 这个问题似乎已解决,无论是您的查询还是我的查询。如果您有后续问题,请打开一个新问题。而这一次事先指定你实际拥有和想要的一切,这样你就不需要再次通过 cmets 进行扩展。
猜你喜欢
  • 1970-01-01
  • 2016-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-21
  • 1970-01-01
  • 1970-01-01
  • 2018-11-15
相关资源
最近更新 更多