【发布时间】:2020-08-07 22:31:47
【问题描述】:
我有一个这样的专栏 -
XXX_2019
234
2142
1423
4634
7886
3143
3243
我要输出
XXX_2019
3 hours, 54 minutes
1 days, 11 hours, 42 minutes
23 hours, 43 minutes
这不是日期时间。这只是一个分钟专栏。我正在使用 Vertica。
【问题讨论】:
我有一个这样的专栏 -
XXX_2019
234
2142
1423
4634
7886
3143
3243
我要输出
XXX_2019
3 hours, 54 minutes
1 days, 11 hours, 42 minutes
23 hours, 43 minutes
这不是日期时间。这只是一个分钟专栏。我正在使用 Vertica。
【问题讨论】:
您可以直接执行此操作。像这样的:
select trim(leading ', ' from
(case when XXX_2019 > 24*60 then ', ' || floor(xxx_2019 / (24*60)) || ' days' else '' end) ||
(case when XXX_2019 > 60 then ', ' || floor((xxx_2019 % (24*60)) / 60) || ' hours' else '' end) ||
(', ' || xxx_2019 % 60 || ' minutes')
)
from (values (12345), (123), (12)) v(xxx_2019);
Here 是一个 dbfiddle(使用 Postgres)。
【讨论】:
XXX_2019 有一个小数部分。运算符% 是模运算符,如果两个参数都是整数,则返回一个整数。
让 Vertica 为您完成繁重的工作。
从分钟计数中提取一个区间,然后从区间中提取日、小时和分钟,并将它们转换为逗号、计数器和单位,连接所有,并删除初始逗号:
WITH
-- your input
input( xxx_2019 ) AS (
SELECT 234
UNION ALL SELECT 2142
UNION ALL SELECT 1423
UNION ALL SELECT 4634
UNION ALL SELECT 7886
UNION ALL SELECT 3143
UNION ALL SELECT 3243
)
-- 从分钟数中得出一个间隔
,
with_interval AS (
SELECT
xxx_2019
, (xxx_2019::char(8)||' minutes')::INTERVAL as dircast
FROM input
)
--最后,从区间中提取位,并格式化
SELECT
dircast
, REGEXP_REPLACE(
CASE EXTRACT(DAY FROM dircast)
WHEN 0 THEN ''
ELSE ', '||EXTRACT(DAY FROM dircast)::VARCHAR(5)||' days'
END
|| CASE EXTRACT(HOUR FROM dircast)
WHEN 0 THEN ''
ELSE ', '||EXTRACT(HOUR FROM dircast)::VARCHAR(5)||' hours'
END
|| CASE EXTRACT(MIN FROM dircast)
WHEN 0 THEN ''
ELSE ', '||EXTRACT(MIN FROM dircast)::VARCHAR(5)||' minutes'
END
, '^, ','') AS s
FROM with_interval
-- out dircast | s
-- out ---------+------------------------------
-- out 03:54 | 3 hours, 54 minutes
-- out 1 11:42 | 1 days, 11 hours, 42 minutes
-- out 23:43 | 23 hours, 43 minutes
-- out 3 05:14 | 3 days, 5 hours, 14 minutes
-- out 5 11:26 | 5 days, 11 hours, 26 minutes
-- out 2 04:23 | 2 days, 4 hours, 23 minutes
-- out 2 06:03 | 2 days, 6 hours, 3 minutes
当然也可以直接,例如:
EXTRACT(DAY FROM (xxx_2019::char(8)||' minutes')::INTERVAL)
但我发现它的另一种方式更具可读性......
当然,您可以使用 @Gordon Linoff 的方法,但我会在 Vertica 中使用整数除法运算符,即双斜线 //,而不是 FLOOR()-ing之后的除法 - 只是为了保持在整数运算范围内,这比浮点运算要快得多。让我迂腐的头脑感到不安的是 INTEGER 隐含地转换为字符,然后将其与字符串连接......
SELECT
TRIM(LEADING ', ' FROM
CASE
WHEN XXX_2019 > 24*60
THEN ', ' || ( XXX_2019 // (24*60) )::VARCHAR(5)|| ' days'
ELSE ''
END
||CASE
WHEN XXX_2019 > 60
THEN ', ' || ( (XXX_2019 % (24*60)) // 60 )::VARCHAR(5)|| ' hours'
ELSE ''
END
||', ' || (xxx_2019 % 60) ::VARCHAR(5)|| ' minutes'
)
FROM input;
【讨论】: