3

Amazonの赤方偏移をいじってテストし始めたところです。SQLで簡単にできることの1つは、useripを整数に変更することです。これは、mssql で parsename を使用して IP 番号を分割するスカラー関数を使用して行われ、定数によってそれらの倍数になります。

 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(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), ' .') ) * 256) + (REVERSE( 左 (REVERSE(ip_address), STRPOS(REVERSE(ip_address), '.')-1) ) * 1 )'.')+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 )'.')+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 )

4

2 に答える 2

2

うわー、私の目はそのクエリを見て涙が出ますが、Redshift によって課せられた制限を考えると、選択の余地はないと確信しています。

こんなに面倒なことをしなければならないことに今でも驚いています。少なくとも、SQL整理する関数を 1 つまたは 2 つ作成できませんか? または、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(これは、データ型が保持されていて、ParAccel が PostgreSQL から分岐したときにこの機能が PostgreSQL 8.1 に存在していた場合、Redshift でも機能する可能性があります)。

inet余談ですが、PostgreSQL では from から bigint へのキャストが定義されていないことに非常に驚きまし'127.0.0.1'::inet::bigintCAST(CAST('127.0.0.1' AS inet) AS bigint)

于 2013-06-29T12:14:29.560 に答える
1

split_part(ip, '.', n)するべきです。

于 2013-06-28T21:39:21.790 に答える