刚刚开始玩游戏并测试亚马逊的红移。我需要做的一件事就是我可以在sql中轻松完成将userip更改为整数。这是在mssql中使用标量函数完成的,该函数使用parsename来分解ip numbres和它们的常数。
CAST(
(CAST(PARSENAME(@IP,4) AS BIGINT) * 16777216) +
(CAST(PARSENAME(@IP,3) AS BIGINT) * 65536) +
(CAST(PARSENAME(@IP,2) AS BIGINT) * 256) +
CAST(PARSENAME(@IP,1) AS BIGINT)
AS BIGINT)
这就是它看起来喜欢参考的东西。
正如我所料,parsename不是redshift中的函数,因此我的问题就出现了。你们知道我可以达到同样的方式吗?
想出来:
(LEFT(ip_address,STRPOS(ip_address,'。') - 1)* 16777216)+(LEFT(SUBSTRING(ip_address,LEN(LEFT(ip_address,STRPOS(ip_address,'。')+ 1)),LEN (ip_address) - LEN(LEFT(ip_address,STRPOS(ip_address,'。') - 1)) - LEN(LEFT(REVERSE(ip_address),STRPOS(REVERSE(ip_address),'。') - 1)) - 2) ,STRPOS(SUBSTRING(ip_address,LEN(LEFT(ip_address,STRPOS(ip_address,'。')+ 1)),LEN(ip_address) - LEN(LEFT(ip_address,STRPOS(ip_address,'。') - 1)) - LEN(LEFT(REVERSE(ip_address),STRPOS(REVERSE(ip_address),'。') - 1)) - 2),'。') - 1)* 65536)+(RIGHT(SUBSTRING(ip_address,LEN(LEFT( ip_address,STRPOS(ip_address,'。')+ 1)),LEN(ip_address) - LEN(LEFT(ip_address,STRPOS(ip_address,'。') - 1)) - LEN(LEFT(REVERSE(ip_address),STRPOS( REVERSE(ip_address),'。') - 1)) - 2),LEN(SUBSTRING(ip_address,LEN(LEFT(ip_address,STRPOS(ip_address,'。')+ 1)),LEN(ip_address) - LEN(左) (ip_address,STRPOS(ip_address,'。') - 1)) - LEN(LEFT(REVERSE(ip_address),STRPOS(REVERSE(ip_address),'。') - 1)) - 2)) - STRPOS(SUBSTRING(ip_address) ,LEN(L EFT(ip_address,STRPOS(ip_address,'。')+ 1)),LEN(ip_address) - LEN(LEFT(ip_address,STRPOS(ip_address,'。') - 1)) - LEN(LEFT(REVERSE(ip_address), STRPOS(REVERSE(ip_address),'。') - 1)) - 2),'。'))* 256)+(REVERSE(LEFT(REVERSE(ip_address),STRPOS(REVERSE(ip_address),'。') - 1))* 1)
答案 0 :(得分:2)
我仍然感到惊讶,你必须做一些非常繁琐的事情。难道你不能至少创建一个或两个SQL
函数来整理它吗?或者Redshift甚至不支持CREATE FUNCTION ... LANGUAGE sql
?
作为参考,在适当的PostgreSQL中你可以做到:
select (split_part(ip, '.', 1)::bigint << 24) +
(split_part(ip, '.', 2)::bigint << 16) +
(split_part(ip, '.', 3)::bigint << 8) +
(split_part(ip, '.', 4)::bigint);
或使用简单的SQL函数:
CREATE OR REPLACE FUNCTION inet_to_bigint(inet) AS $$
SELECT sum(split_part($1::text,'.',octetnum)::bigint << (32 - octetnum*8))
FROM generate_series(1,4) octetnum;
$$ LANGUAGE sql;
通过滥用inet
数据类型的减法运算符,或几乎可以肯定最有效:
SELECT (ip - '0.0.0.0')
(如果他们保留了inet
数据类型,并且如果此功能在PostgreSQL 8.1中存在,当ParAccel从PostgreSQL派生时,这个功能甚至可以在Redshift中工作。
另一方面,我很惊讶地看到在PostgreSQL中没有从inet
到bigint定义的强制转换,因为我希望能够写出'127.0.0.1'::inet::bigint
,这将是速记CAST(CAST('127.0.0.1' AS inet) AS bigint)
。
答案 1 :(得分:1)
split_part(ip, '.', n)
应该这样做。