如何在 Presto 中将小时解析为人类可读的字符串? (十进制到时间)
How to parse hours into human readable string in Presto? (decimal to time)
我是运行以下
SELECT A, B, AVG(date_diff('hour', creation_date,current_timestamp)) as AVG_in_hours
FROM table
GROUP BY A,B
这给了我:
A B AVG_in_hours
1 2 1587.25
1 3 159.43283582089552
1 4 1
我希望它是:
A B AVG_in_hours AVG_TEXT
1 2 1587.25 66 days, 3 hours, 15 minutes
1 3 159.43283582089552 6 days, 15 hours, 25 minutes
1 4 1 1 hours, 0 minutes
基本上是将十进制的AVG_in_hours
转换成可读的字符串。
我只需要天数、小时数和分钟数。
如何快速完成此操作?
试试这个代码。我没有测试它:
with raw_data as (
SELECT A, B, AVG(date_diff('hour', creation_date,current_timestamp)) as AVG_in_hours,
AVG(date_diff('day', creation_date,current_timestamp)) as days,
AVG(date_diff('hour', creation_date,current_timestamp))-
AVG(date_diff('day', creation_date,current_timestamp))*24 as hrs,
AVG(date_diff('minute', creation_date,current_timestamp))-
AVG(date_diff('hour', creation_date,current_timestamp))*60 as minutes
FROM table
GROUP BY A,B
)
select a,b, AVG_in_hours,
(case
when round(days)=0 then cast(round(days) as varchar) || ' days, '
else '' end)
|| cast(round(hrs) as varchar) || ' hours, ' || cast(round(minutes) as varchar) || ' minutes' as AVG_TEXT
from raw_data
您可以试试下面的代码。为您的数据库稍微更改它,因为它是为 SQL_Server 编写的。逻辑基本上是检查 avg_in_minutes 的值,如果它超过 1440 分钟(等于 1 天)或超过 60 分钟(等于一小时),然后使用计算来扣除天数,小时,剩下的是分钟。
WITH test (A, B, insert_date) AS
(SELECT 1, 2 , '2020-05-01' UNION
SELECT 1, 2 , '2020-05-02' UNION
SELECT 1, 2 , '2020-05-12' UNION
SELECT 1, 3 , '2020-05-01' UNION
SELECT 1, 3 , '2020-05-10' UNION
SELECT 1, 4 , '2020-05-01' UNION
SELECT 1, 5 , '2020-05-03'
)
SELECT *,
CASE WHEN AVG_in_minutes > 1440
THEN CAST((AVG_in_minutes - (AVG_in_minutes % 1440))/1440 AS VARCHAR) + ' days, '
+ CAST(((AVG_in_minutes%1440 - (AVG_in_minutes%1440)%60)/60) AS VARCHAR) + ' hours, '
+ CAST(((AVG_in_minutes%1440)%60) AS VARCHAR) + ' minutes'
WHEN AVG_in_minutes > 60
THEN CAST(((AVG_in_minutes%1440 - (AVG_in_minutes%1440)%60)/60) AS VARCHAR) + ' hours, '
+ CAST(((AVG_in_minutes%1440)%60) AS VARCHAR) + ' minutes'
ELSE CAST(((AVG_in_minutes%1440)%60) AS VARCHAR) + ' minutes'
END AS AVG_in_Text
FROM
(
SELECT A, B,
AVG(datediff(MINUTE, insert_date,current_timestamp)) AS AVG_in_minutes
from test
GROUP BY A,B
) test_final
我是运行以下
SELECT A, B, AVG(date_diff('hour', creation_date,current_timestamp)) as AVG_in_hours
FROM table
GROUP BY A,B
这给了我:
A B AVG_in_hours
1 2 1587.25
1 3 159.43283582089552
1 4 1
我希望它是:
A B AVG_in_hours AVG_TEXT
1 2 1587.25 66 days, 3 hours, 15 minutes
1 3 159.43283582089552 6 days, 15 hours, 25 minutes
1 4 1 1 hours, 0 minutes
基本上是将十进制的AVG_in_hours
转换成可读的字符串。
我只需要天数、小时数和分钟数。
如何快速完成此操作?
试试这个代码。我没有测试它:
with raw_data as (
SELECT A, B, AVG(date_diff('hour', creation_date,current_timestamp)) as AVG_in_hours,
AVG(date_diff('day', creation_date,current_timestamp)) as days,
AVG(date_diff('hour', creation_date,current_timestamp))-
AVG(date_diff('day', creation_date,current_timestamp))*24 as hrs,
AVG(date_diff('minute', creation_date,current_timestamp))-
AVG(date_diff('hour', creation_date,current_timestamp))*60 as minutes
FROM table
GROUP BY A,B
)
select a,b, AVG_in_hours,
(case
when round(days)=0 then cast(round(days) as varchar) || ' days, '
else '' end)
|| cast(round(hrs) as varchar) || ' hours, ' || cast(round(minutes) as varchar) || ' minutes' as AVG_TEXT
from raw_data
您可以试试下面的代码。为您的数据库稍微更改它,因为它是为 SQL_Server 编写的。逻辑基本上是检查 avg_in_minutes 的值,如果它超过 1440 分钟(等于 1 天)或超过 60 分钟(等于一小时),然后使用计算来扣除天数,小时,剩下的是分钟。
WITH test (A, B, insert_date) AS
(SELECT 1, 2 , '2020-05-01' UNION
SELECT 1, 2 , '2020-05-02' UNION
SELECT 1, 2 , '2020-05-12' UNION
SELECT 1, 3 , '2020-05-01' UNION
SELECT 1, 3 , '2020-05-10' UNION
SELECT 1, 4 , '2020-05-01' UNION
SELECT 1, 5 , '2020-05-03'
)
SELECT *,
CASE WHEN AVG_in_minutes > 1440
THEN CAST((AVG_in_minutes - (AVG_in_minutes % 1440))/1440 AS VARCHAR) + ' days, '
+ CAST(((AVG_in_minutes%1440 - (AVG_in_minutes%1440)%60)/60) AS VARCHAR) + ' hours, '
+ CAST(((AVG_in_minutes%1440)%60) AS VARCHAR) + ' minutes'
WHEN AVG_in_minutes > 60
THEN CAST(((AVG_in_minutes%1440 - (AVG_in_minutes%1440)%60)/60) AS VARCHAR) + ' hours, '
+ CAST(((AVG_in_minutes%1440)%60) AS VARCHAR) + ' minutes'
ELSE CAST(((AVG_in_minutes%1440)%60) AS VARCHAR) + ' minutes'
END AS AVG_in_Text
FROM
(
SELECT A, B,
AVG(datediff(MINUTE, insert_date,current_timestamp)) AS AVG_in_minutes
from test
GROUP BY A,B
) test_final