如何在Oracle中对存储为varchar2的IP地址进行排序?

时间:2014-04-12 23:52:43

标签: sql oracle

如何对存储为varchar2的数字IP地址进行排序?我希望地址按“自然”数字顺序而不是字典顺序排序(例如'1.1.1.10'之前的'1.1.1.9')。

2 个答案:

答案 0 :(得分:1)

你可以使用regexp_replace用前导零填充每个八位字节 1.1.1.9将转换为001.001.001.009

create table t (a varchar2(16));
insert into t values('10.1.1.1');
insert into t values('10.1.1.9');
insert into t values('10.1.1.10');

select * from t order by regexp_replace(regexp_replace(a,'(\d+)','00\1'),'0*(\d{3})','\1');

a
-
10.1.1.1
10.1.1.9
10.1.1.10

如果考虑性能,您可以考虑创建基于函数的索引或在存储之前将IP地址转换为数字。

create index ix on t (regexp_replace(regexp_replace(a,'(\d+)','00\1'),'0*(\d{3})','\1'));

答案 1 :(得分:0)

您可以创建一个将其转换为十进制数的函数:

CREATE OR REPLACE FUNCTION Ip2Decimal(IP IN VARCHAR2) RETURN INTEGER DETERMINISTIC IS
    DecimalIp INTEGER := 0;
BEGIN
    IF Ip IS NULL THEN 
        RETURN NULL; 
    END IF;
    FOR i IN 1..4 LOOP
        DecimalIp := DecimalIp + REGEXP_SUBSTR(IP, '\d+', 1, i) * 256**(4-i);
    END LOOP;
    RETURN DecimalIp;
END Ip2Decimal;

然后按此函数值排序。在这种情况下,基于函数的索引应该是有用的。