在红移中创建Python UDF以替换字符串中的字符
我的数据库中有一个varchar列。它应该有'43','43000','50000'等值,但有时它有'43000','50','00000'等值,有时它也有垃圾值和其他字符 我要做的是,首先替换值中的所有在红移中创建Python UDF以替换字符串中的字符,python,replace,amazon-redshift,user-defined-functions,Python,Replace,Amazon Redshift,User Defined Functions,我的数据库中有一个varchar列。它应该有'43','43000','50000'等值,但有时它有'43000','50','00000'等值,有时它也有垃圾值和其他字符 我要做的是,首先替换值中的所有,“,然后尝试将其转换为int,如果成功,则返回此int值。否则返回null。我正试图为它编写一个Python UDF,但它似乎不起作用。这是: create or replace function isnumeric (aval VARCHAR(20000)) returns int IM
,“
,然后尝试将其转换为int
,如果成功,则返回此int
值。否则返回null
。我正试图为它编写一个Python UDF,但它似乎不起作用。这是:
create or replace function isnumeric (aval VARCHAR(20000))
returns int
IMMUTABLE
as $$
try:
aval = aval.replace(',','');
x = int(aval);
return x;
except:
return (1==2);
return null;
$$ language plpythonu;
select
isnumeric(field1)
from
table
limit 10000
谁能帮我一下吗?我认为你不需要自定义项。您可以使用
REGEXP\u INSTR
查找无效值,然后使用REGEXP\u REPLACE
清除有效字符串中的非数字字符
WITH test_vals AS
( SELECT 'garbage_1' test, 'xx43,000' val
UNION ALL SELECT 'decimal' test, '43,000.00' val
UNION ALL SELECT 'commas' test, '50,00,000' val
UNION ALL SELECT 'date_val' test, '2019/03/03' val
)
SELECT test
--Any character other than numbers, commas or decimal returns NULL
, CASE WHEN REGEXP_INSTR(val,'[^0-9,.]') > 0 THEN NULL
--Commas are removed, decimal marker is retained
ELSE REGEXP_REPLACE(val,'[^0-9.]','') END::NUMERIC AS ouput
FROM test_vals
;
输出为:
test | ouput
-----------+---------
garbage_1 |
decimal | 43000
commas | 5000000
date_val |
你能告诉我们程序给出的输出和/或错误吗?如果您能确切地告诉我们它在做什么和不在做什么,我们可以提供更多帮助。@TechPerson我得到的操作无效:布尔类型的输入语法无效:“null”;您的UDF应该返回
int
,而不是bool
。Python中没有null
的概念。相反,它使用None
。如果返回None
,我不知道Redshift如何处理它,但它可能会将其转换为NULL
。试试看。(或者,坦率地说,使用下面乔的CAST
想法,哪个更好。)@JohnRotenstein对于下面乔的想法,我在评论中提到了为什么不能使用它。我尝试将null替换为None,但udf仍然只返回布尔值。它返回布尔值,因为第二行显示“returns bool”。但问题是我只想替换“,”,如果列值包含任何其他字符,我只想把它转换成null,而不是在我的计算中考虑这个值。这是因为如果列包含43000的值,将它们转换为43000是有效的。但是,一些垃圾值包括2019/03/03,但将其转换为20190303是不正确的,因为此列是价格列,有人输入了垃圾日期值。所以我想在计算中忽略它。修改了示例以解决删除无效条目的用例。然而,我建议在这一点上要谨慎。如果数据完全是自由形式的,那么任何深入的分析充其量也可能是不可靠的。祝你好运