2013-06-28 28 views
2

刚开始玩耍并测试亚马逊的红移。有一件事我需要做的,我可以很容易地在SQL中做的是改变userip为整数。这是在mssql中用一个标量函数完成的,该标量函数使用parsename来分解ip numbres,并通过常量分解它们。如何将userip转换为AMAZON REDSHIFT中的整数

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不是红移的功能,因此我的问题就出现了。你们知道我可以达到同样的目标吗?

想通了:

(LEFT(IP地址,STRPOS(IP地址) - 1)* 16777216”。 ')+(LEFT(SUBSTRING(IP地址,LEN(LEFT(IP地址,STRPOS(IP地址,' ')+ 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 (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(LEFT(ip_address,STRPOS(ip_address,'。') - 1)) - LEN(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),'。'))* 256)+(REVERSE(LEFT(REVERSE(ip_address),STRPOS(REVERSE(ip_address),'。') - 1))* 1)

+0

想出来, –

+0

“in sql” - >“在Microsoft SQL Server中”?“SQL”是查询语言,它不是产品。感谢你提到你正在使用Redshift(ParAccel的一个非常老的PostgreSQL版本的私有分支),不仅仅是说“PostgreSQL”。另外,如果可能的话,最好发布自己的问题的答案,而不是编辑你的答案。 –

回答

1

split_part(ip, '.', n)做到这一点。

+0

我试着使用已经@ jakub,但是当使用亚马逊红移时,split_part不会在主节点之外工作。 –

+2

@PatRickAllen这些东西在原始问题中值得一提。 “我已经试过......”。亚马逊并没有提供方便的方式来测试Redshift上的东西(没有SQLFiddle等效,没有免费的测试服务器等),所以如果你标记一个问题[tag:postgresql],人们会回答PostgreSQL的答案。 –

2

哇,看到那个查询后,我的眼睛正在浇水,但我相信在Redshift限制下你没有多少选择。

我还是很惊讶你必须做一些相当麻烦的事情。你不能至少创建一个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') 

(这个人甚至可能在R如果他们保留了inet数据类型,并且这个特性在PostgreSQL 8.1中存在,那么当ParAccel从PostgreSQL中分离时)。

在一个侧面说明,我很惊讶地看到,有没有从inet定义为bigint投,PostgreSQL中,如我所料,只是能写'127.0.0.1'::inet::bigint,这将是简写CAST(CAST('127.0.0.1' AS inet) AS bigint)

+1

Redshift不支持功能,或IP类型 –

+0

+1。 。 。第一个解决方案似乎在RedShift中起作用。 –