我有一个表持续时间:
-------------------------------
| id | from | to |
|----|------------|-----------|
| 1 | 2011-02-22 | NULL |
| 2 | 1999-08-03 |2005-03-30 |
| 3 | 1982-09-03 |1988-01-30 |
| 4 | 1965-12-01 |1980-05-02 |
-------------------------------
我想计算连续的时间差(往返)并将它们相加。我的查询是:
SELECT CONCAT(SUM(TIMESTAMPDIFF( YEAR, from, IF(to IS NULL,'2017-10-
18', to))),' Years ',
SUM(TIMESTAMPDIFF( MONTH, from, IF(to IS NULL,'2017-10-18', to))
% 12),' Months ',
SUM(FLOOR( TIMESTAMPDIFF( DAY, from, IF(to IS NULL,'2017-10-18',
to)) % 30.4375 )),' Days ') AS Duration
FROM duration;
我得到:
------------------------------
| Duration |
|----------------------------|
| 30 Years 23 Months 78 Days |
------------------------------
但我想得到:
-----------------------------
| Duration |
|---------------------------|
| 32 Years 1 Months 18 Days |
-----------------------------
请帮忙!
最佳答案
我尝试在下面提出一系列查询,以显示确定以年/月/日为单位的持续时间的准确方法(尽管这些计算结果为32 年 1 个月 22 天(可能是由于“现在”的变化),并且我没有添加最终的连接,这并不难实现。所使用的方法每行都是准确的,但确实依赖于每月天数的近似值(30.4375 *) 用于最终计算月份和日期。
TIMESTAMPDIFF(YEAR , from_dt, to_dt )
给出每行的年数TIMESTAMPDIFF(MONTH, from_dt + INTERVAL TIMESTAMPDIFF(YEAR , from_dt, to_dt) YEAR , to_dt )
将年数添加到开始日期,然后获取该日期与结束日期的差值几个月内TIMESTAMPDIFF(DAY , from_dt + INTERVAL TIMESTAMPDIFF(MONTH, from_dt, to_dt) MONTH , to_dt )
现在将总月数添加到开始日期,然后计算到达结束日期的剩余时间日期- 请注意,如果给定开始日期 + 年 + 月 + 天,则可以准确地重新计算结束日期(请参阅查询 4)
注意:我在下面的查询中使用了多个“层”,使它们更易于阅读(我希望)。
MySQL 5.6 架构设置:
CREATE TABLE duration
(
from_dt DATE, to_dt DATE
);
INSERT INTO duration
VALUES ('2011-02-22', NULL )
, ('1999-08-03', '2005-03-30' )
, ('1982-09-03', '1988-01-30' )
, ('1965-12-01', '1980-05-02' )
;
查询 1:
## adjusted sums( method using timestampdiff )
SELECT
CASE WHEN SUM(d.months) > 12 THEN SUM(d.years) + FLOOR(SUM(d.years/12)) ELSE SUM(d.years) END
as years
, CASE WHEN SUM(d.days) > 30 THEN FLOOR(((SUM(d.months) + FLOOR(SUM(d.days/30.4375)))/12)) ELSE SUM(d.months) END
as months
, CASE WHEN SUM(d.days) > 30 THEN FLOOR(MOD(SUM(d.days), 30)) ELSE SUM(d.months) END
as days
, current_date
FROM (
SELECT
TIMESTAMPDIFF(YEAR , from_dt, to_dt )
as years
, TIMESTAMPDIFF(MONTH, from_dt + INTERVAL TIMESTAMPDIFF(YEAR , from_dt, to_dt) YEAR , to_dt )
as months
, TIMESTAMPDIFF(DAY , from_dt + INTERVAL TIMESTAMPDIFF(MONTH, from_dt, to_dt) MONTH , to_dt )
as days
FROM (
SELECT
from_dt
, COALESCE(to_dt,CURRENT_DATE) to_dt
FROM duration
) d2
) d
<强> Results :
| years | months | days | current_date |
|-------|--------|------|--------------|
| 32 | 2 | 22 | 2017-10-19 |
查询 2:
## simple sums( method using timestampdiff )
SELECT
sum(TIMESTAMPDIFF(YEAR , from_dt, to_dt ))
years
, sum(TIMESTAMPDIFF(MONTH, from_dt + INTERVAL TIMESTAMPDIFF(YEAR , from_dt, to_dt) YEAR , to_dt ))
months
, sum(TIMESTAMPDIFF(DAY , from_dt + INTERVAL TIMESTAMPDIFF(MONTH, from_dt, to_dt) MONTH , to_dt ))
days
, current_date
FROM (
SELECT
from_dt
, COALESCE(to_dt,CURRENT_DATE) to_dt
FROM duration
) d
<强> Results :
| years | months | days | current_date |
|-------|--------|------|--------------|
| 30 | 23 | 82 | 2017-10-19 |
查询 3:
## method using timestampdiff
SELECT
d.*
, TIMESTAMPDIFF(YEAR , from_dt, to_dt ) AS diff_yr
, TIMESTAMPDIFF(MONTH, from_dt + INTERVAL TIMESTAMPDIFF(YEAR , from_dt, to_dt) YEAR , to_dt ) AS diff_mn
, TIMESTAMPDIFF(DAY , from_dt + INTERVAL TIMESTAMPDIFF(MONTH, from_dt, to_dt) MONTH , to_dt ) AS diff_dy
FROM (
SELECT
from_dt
, COALESCE(to_dt,CURRENT_DATE) to_dt
, current_date
FROM duration
) d
<强> Results :
| from_dt | to_dt | current_date | diff_yr | diff_mn | diff_dy |
|------------|------------|--------------|---------|---------|---------|
| 2011-02-22 | 2017-10-19 | 2017-10-19 | 6 | 7 | 27 |
| 1999-08-03 | 2005-03-30 | 2017-10-19 | 5 | 7 | 27 |
| 1982-09-03 | 1988-01-30 | 2017-10-19 | 5 | 4 | 27 |
| 1965-12-01 | 1980-05-02 | 2017-10-19 | 14 | 5 | 1 |
查询 4:
## testing (method using timestampdiff)
## is able to reproduce to_dt ?
select
from_dt
, to_dt
, from_dt + INTERVAL diff_yr YEAR
+ INTERVAL diff_mn MONTH
+ INTERVAL diff_dy DAY
recalculated_to_dt
, current_date
FROM (
SELECT
d.*
, TIMESTAMPDIFF(YEAR , from_dt, to_dt ) AS diff_yr
, TIMESTAMPDIFF(MONTH, from_dt + INTERVAL TIMESTAMPDIFF(YEAR , from_dt, to_dt) YEAR , to_dt ) AS diff_mn
, TIMESTAMPDIFF(DAY , from_dt + INTERVAL TIMESTAMPDIFF(MONTH, from_dt, to_dt) MONTH , to_dt ) AS diff_dy
FROM (
SELECT
from_dt
, COALESCE(to_dt,CURRENT_DATE) to_dt
FROM duration
) d
) d2
<强> Results :
| from_dt | to_dt | recalculated_to_dt | current_date |
|------------|------------|--------------------|--------------|
| 2011-02-22 | 2017-10-19 | 2017-10-19 | 2017-10-19 |
| 1999-08-03 | 2005-03-30 | 2005-03-30 | 2017-10-19 |
| 1982-09-03 | 1988-01-30 | 1988-01-30 | 2017-10-19 |
| 1965-12-01 | 1980-05-02 | 1980-05-02 | 2017-10-19 |
- 30.4375我相信是〜(一个世纪的天数)/120
关于mysql - 如何在MySQL中以年、月、日为单位求和持续时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46816341/