如何在 Impala/hive 中重新格式化多个不同的日期
How to reformat multiple different dates in Impala/hive
在table中,有以各种格式保存的日期。例如
19/Jun/1965
30-Jun-1980
29-Mar-1970
Jun-12-1969
我希望它们都以相同的格式保存。我正在尝试将其分类为子集并解决每个问题的方法
select birthdate,
case
when birthdate like '%-%' then cast(unix_timestamp(birthdate, 'dd-MMM-yyyy') as timestamp)
when birthdate like '%/%' then cast(unix_timestamp(birthdate, 'dd/MMM/yyyy') as timestamp)
end from patientinfo;
但这可能会导致多个嵌套的 case-when 查询。
是否有更好的方法将所有数据转换为相同的日期格式?
是的,你可以。
您可以编写自己的 UDF 函数来执行类似 的操作。
您需要遍历所有可能的格式并尝试验证每种格式的数据。在无效的情况下,return 消息或默认值,例如“1000-01-01”。
您可以查看 here 如何构建 UDF 函数。
祝你好运!
正如 F.Lazarescu 指出的那样,您可以使用 'external' 工具作为 UDF(如果您习惯使用它们以及 Java 或 C++ 等语言,这可能会更容易)或您可以简单地使用正则表达式。
Impala 为此提供了 regexp_extract。我做了一个查询,您可以将其用于上述日期。
如果您的日期可能有其他语法,您应该将其添加到正则表达式可能性中:
select date_time,
case
when
-- If it starts with a number(day)
regexp_extract(date_time, '^(\d+).*?', 1)!='' THEN
cast(unix_timestamp(
concat(
regexp_extract(date_time, '^(\d+).*?', 1),-- Day
'/',
-- Extract and convert the month
case
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='Jan' then '01'
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='Feb' then '02'
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='Mar' then '03'
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='Apr' then '04'
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='May' then '05'
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='Jun' then '06'
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='Jul' then '07'
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='Aug' then '08'
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='Sep' then '09'
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='Oct' then '10'
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='Nov' then '11'
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='Dec' then '12'
else null
end,
'/',
regexp_extract(fecha, '(\d+)$', 1)
),
'dd/MM/yyyy') as timestamp)
WHEN
-- If it starts with an String (month)
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1) !='' then
cast(unix_timestamp(
concat(
regexp_extract(date_time, '(\d+)', 1),-- Day
'/',
case
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='Jan' then '01'
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='Feb' then '02'
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='Mar' then '03'
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='Apr' then '04'
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='May' then '05'
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='Jun' then '06'
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='Jul' then '07'
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='Aug' then '08'
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='Sep' then '09'
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='Oct' then '10'
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='Nov' then '11'
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='Dec' then '12'
else null
end,
'/',
regexp_extract(date_time, '(\d+)$', 1)),
'dd/MM/yyyy') as timestamp)
else null
end as converted_datetime
from mytable;
希望对您有所帮助。
在table中,有以各种格式保存的日期。例如
19/Jun/1965
30-Jun-1980
29-Mar-1970
Jun-12-1969
我希望它们都以相同的格式保存。我正在尝试将其分类为子集并解决每个问题的方法
select birthdate,
case
when birthdate like '%-%' then cast(unix_timestamp(birthdate, 'dd-MMM-yyyy') as timestamp)
when birthdate like '%/%' then cast(unix_timestamp(birthdate, 'dd/MMM/yyyy') as timestamp)
end from patientinfo;
但这可能会导致多个嵌套的 case-when 查询。
是否有更好的方法将所有数据转换为相同的日期格式?
是的,你可以。
您可以编写自己的 UDF 函数来执行类似
您可以查看 here 如何构建 UDF 函数。
祝你好运!
正如 F.Lazarescu 指出的那样,您可以使用 'external' 工具作为 UDF(如果您习惯使用它们以及 Java 或 C++ 等语言,这可能会更容易)或您可以简单地使用正则表达式。
Impala 为此提供了 regexp_extract。我做了一个查询,您可以将其用于上述日期。
如果您的日期可能有其他语法,您应该将其添加到正则表达式可能性中:
select date_time,
case
when
-- If it starts with a number(day)
regexp_extract(date_time, '^(\d+).*?', 1)!='' THEN
cast(unix_timestamp(
concat(
regexp_extract(date_time, '^(\d+).*?', 1),-- Day
'/',
-- Extract and convert the month
case
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='Jan' then '01'
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='Feb' then '02'
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='Mar' then '03'
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='Apr' then '04'
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='May' then '05'
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='Jun' then '06'
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='Jul' then '07'
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='Aug' then '08'
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='Sep' then '09'
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='Oct' then '10'
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='Nov' then '11'
when
regexp_extract(date_time, '([a-zA-Z]+?)', 1)='Dec' then '12'
else null
end,
'/',
regexp_extract(fecha, '(\d+)$', 1)
),
'dd/MM/yyyy') as timestamp)
WHEN
-- If it starts with an String (month)
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1) !='' then
cast(unix_timestamp(
concat(
regexp_extract(date_time, '(\d+)', 1),-- Day
'/',
case
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='Jan' then '01'
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='Feb' then '02'
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='Mar' then '03'
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='Apr' then '04'
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='May' then '05'
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='Jun' then '06'
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='Jul' then '07'
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='Aug' then '08'
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='Sep' then '09'
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='Oct' then '10'
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='Nov' then '11'
when
regexp_extract(date_time, '^([a-zA-Z]+).*?', 1)='Dec' then '12'
else null
end,
'/',
regexp_extract(date_time, '(\d+)$', 1)),
'dd/MM/yyyy') as timestamp)
else null
end as converted_datetime
from mytable;
希望对您有所帮助。