IP-Adressen sortieren

By Frank Kalis

Posted on Sep 6, 2004 von in SQL Server

Nun, grundsätzlich würde ich wahrscheinlich eher zu einem anderen Datentyp als VARCHAR tendieren, um IP Adressen zu speichern, aber dennoch fand ich diese "Koproduktion" der beiden SQL Server MVP's Steve Kass und Itzik Ben-Gan in der englischen Newsgroup sehr interessant. Folgender Lösungsansatz kam von Steve Kass

create table T (
ipAdd varchar(15)
)
insert into T
select
rtrim(abs(binary_checksum(newid()))%256) + '.'
+ rtrim(abs(binary_checksum(newid()))%256) + '.'
+ rtrim(abs(binary_checksum(newid()))%256) + '.'
+ rtrim(abs(binary_checksum(newid()))%256)
from Northwind..Orders
go

-- sort by ipAdd
select ipAdd
from T
order by
0 + parsename(ipAdd,4),
0 + parsename(ipAdd,3),
0 + parsename(ipAdd,2),
0 + parsename(ipAdd,1)
go

So, ausgehend von dieser Beispieltabelle T kam dann folgender Vorschlag von Itzik Ben-Gan:

CREATE VIEW Patterns
AS
SELECT REPLICATE('_',N1.n) + '.'
 + REPLICATE('_',N2.n) + '.'
 + REPLICATE('_',N3.n) + '.'
 + REPLICATE('_',N4.n) AS pattern,
 1 AS s1, N1.n AS l1,
 N1.n+2 AS s2, N2.n AS l2,
 N1.n+N2.n+3 AS s3, N3.n AS l3,
 N1.n+N2.n+N3.n+4 AS s4, N4.n AS l4
FROM Nums AS N1, Nums AS N2, Nums AS N3, Nums AS N4
WHERE N1.n <= 3 AND N2.n <= 3 AND N3.n <= 3 AND N4.n <= 3
GO

SELECT T.*
FROM T JOIN Patterns
 ON ipAdd LIKE pattern
ORDER BY
 CAST(SUBSTRING(ipAdd,s1,l1) AS TINYINT),
 CAST(SUBSTRING(ipAdd,s2,l2) AS TINYINT),
 CAST(SUBSTRING(ipAdd,s3,l3) AS TINYINT),
 CAST(SUBSTRING(ipAdd,s4,l4) AS TINYINT)
GO

Ben-Gan verwendet eine nummerische Hilfstabelle, die in vielen Fällen extrem hilfreich sein kann, und die man mit:

SELECT 
	TOP 1000 n = IDENTITY(INT) 
INTO 
	Nums 
FROM
	Sysobjects S1 
CROSS JOIN 
	Sysobjects S2 

relativ leicht erstellen kann. Zum Schluß kam noch einmal Steve Kass mit einer UDF basierten Lösung:

create function ipVal (
@ipAdd varchar(15)
) returns bigint as begin
declare @a varchar(3), @b varchar(3), @c varchar(3), @d varchar(3)
set @ipAdd = replace(@ipAdd,'.',space(1))
exec master..xp_sscanf @ipAdd, '%s%s%s%s', @a output, @b output, @c 
output, @d output
return 256.*(256.*(256.*@a + @b)+ @c) + @d
end
GO

Die Ergebnismenge ist in allen drei Lösungen identisch und sieht verkürzt so aus:

ipAdd           
--------------- 
0.29.139.218
0.42.28.216
0.112.240.205
1.63.169.105
1.159.167.72
2.168.143.230
3.50.2.153
3.53.44.168
3.95.215.255
3.108.33.169
3.146.81.33
3.168.194.74
3.239.97.179
4.14.61.195
4.81.148.233
4.91.186.46
4.131.70.150
4.138.171.124
4.244.58.66
5.40.88.33
5.61.160.216
5.72.228.141
5.121.171.82
5.136.210.214
5.194.153.107
5.223.170.8
6.14.82.89
6.211.186.133
7.141.188.164
8.120.148.128
8.148.94.165
9.115.251.14
9.173.205.139
9.173.218.157
...
...
Tags: Tags:
Dieser Eintrag wurde eingetragen von und ist abgelegt unter SQL Server. Tags: , ,

Noch kein Feedback


Formular wird geladen...