解析文本的时间间隔

时间:2017-02-20 09:17:40

标签: mysql sql

我有这些数据:

+-------------+----------------------------+
| name        | time_lost                  |
+-------------+----------------------------+
| Break000002 | 7 day 18.0 hours           |
| Break000003 | 0 day 10.0 hours           |
| Break000004 | 1 day 1.52 hours           |
| Break000005 | 2 day 21.0 hours           |
| Break000006 | 1 day 0.416666666667 hours |
| Break000007 | 0 day 1.25 hours           |
| Break000008 | 0 day 2.5 hours            |
| Break000009 | 1 day 0.02 hours           |
+-------------+----------------------------+

我想在此表中计算总time_lost,所以我尝试了这个:

select sum(time_lost) from mytable;

输出:

+----------------+
| sum(time_lost) |
+----------------+
|             12 |
+----------------+

我的问题:

如何解析此字符串以将其转换为时间,请建议我做任何提示。

由于

3 个答案:

答案 0 :(得分:2)

您可以将time_lost列转换为具有以下分数的天数:

LEFT(time_lost, LOCATE(' day', time_lost)-1) + SUBSTR(time_lost, LOCATE(' day', time_lost)+5)/24

然后将其放入SUM()函数。

select sum(LEFT(time_lost, LOCATE(' day', time_lost)-1) + SUBSTR(time_lost, LOCATE(' day', time_lost)+5)/24) AS total_time_lost
from mytable;

您的示例数据的结果将为14.2638 days

答案 1 :(得分:2)

首先使用REPLACE函数2次删除“day”和“hours”,并使用TRIM删除前导和尾随空格

SELECT TRIM(REPLACE(REPLACE(time_lost, 'day ', ''), 'hours', ''))

因此,你最终会得到这个

| Break000002 | 7 18.0           |
| Break000003 | 0 10.0           |
| Break000004 | 1 1.52           |
| Break000005 | 2 21.0           |
| Break000006 | 1 0.416666666667 |
| Break000007 | 0 1.25           |
| Break000008 | 0 2.5            |
| Break000009 | 1 0.02           |

然后使用SUBSTRING_INDEX隔离日期(发现第一个空格之前字符串的左侧部分)

SELECT TRIM(SUBSTRING_INDEX(TRIM(REPLACE(REPLACE(time_lost, 'day', ''), 'hours', '')), ' ',1))

哪个给你这个

| Break000002 | 7|
| Break000003 | 0|                    
| Break000004 | 1|                    
| Break000005 | 2|                    
| Break000006 | 1|                    
| Break000007 | 0|                    
| Break000008 | 0|                    
| Break000009 | 1                    

使用SUBSTRING_INDEX和负数(-1),您可以隔离小时数(从结尾找到第一个空格之前的字符串的右侧部分)

SELECT TRIM(SUBSTRING_INDEX(TRIM(REPLACE(REPLACE(time_lost, 'day', ''), 'hours', '')), ' ',-1))                    

哪个给你这个

| Break000002 | 18.0           |                    
| Break000003 | 10.0           |                    
| Break000004 | 1.52           |                    
| Break000005 | 21.0           |                    
| Break000006 | 0.416666666667 |                    
| Break000007 | 1.25           |                    
| Break000008 | 2.5            |                    
| Break000009 | 0.02           |                    

您还应该将结果转换为数字,因为它们实际上被视为字符串

-- Days as unsigned integer                    
SELECT CAST(TRIM(SUBSTRING_INDEX(TRIM(REPLACE(REPLACE(time_lost, 'day', ''), 'hours', '')), ' ',1)) AS UNSIGNED)                    

-- Hours with 2 digit precision                                                       
SELECT CAST(TRIM(SUBSTRING_INDEX(TRIM(REPLACE(REPLACE(time_lost, 'day', ''), 'hours', '')), ' ',-1)) AS DECIMAL (2,2))                                   

现在您已准备好进行计算

当天,只是SUM。 在几小时内,您必须将它们视为一天的一小部分:日=小时/ 24

SELECT ( 
         SUM(CAST(TRIM(SUBSTRING_INDEX(TRIM(REPLACE(REPLACE(time_lost, 'day', ''), 'hours', '')), ' ',1)) AS UNSIGNED))                                                             
       + SUM(CAST(TRIM(SUBSTRING_INDEX(TRIM(REPLACE(REPLACE(time_lost, 'day', ''), 'hours', '')), ' ',-1)) AS DECIMAL (2,2)) / 24 )
       ) AS total_days  

编辑:有点太晚了

答案 2 :(得分:0)

最简单的解决方案是首先将数据存储为一个时间单位。可能需要几分钟或几秒钟,具体取决于您需要测量它的准确程度。

例如,如果您有分钟数,那么该字段的“SUM”将为您提供所有行中的总分钟数,并且您始终可以将其转换为小时/天/无论何时显示做适当的乘法或除法 - 你可以在这里做,或者它可能更适合你的应用程序的表示层