How to sort table in sql2000 with ipaddress(format x.x.x.x) as column with nvarchar datatype in ascending order
without using stored procedure
Ex:
Table: netComputers(3 rows)
Column Name: ipAddress (string data type)
ipAddress
0.0.18.1
0.1.1.2
0.0.0.1
Sql query : if I use the query
Select ipAddress from netComputers order by cast( replace(ipaddress,'.','') as numeric(12)) asc
Gives result as :
ipAddress
0.0.0.1
0.1.1.2
0.0.18.1
Where as expected result should be:
ipAddress
0.0.0.1
0.0.18.1
0.1.1.2

How to sort table in sql2000 with ipaddress(format x.x.x.x) as column with nvarchar datatype in ascending order
John Ketchpaw
Use PARSENAME
example:
select * from(
select '0.0.18.1' as IpAddress union all
select '0.1.1.2' union all
select '0.0.0.1' ) z
order by parsename(ipaddress,1),
parsename(ipaddress,2),
parsename(ipaddress,3),
parsename(ipaddress,4)
Denis The SQL Menace
SQL blog:http://sqlservercode.blogspot.com/
Netasia
Ah ok. Sorry now I get the idea.
I have a solution but you need to have fixed length of the IP address field. It will be much easier to sort without using Stored Proc
ip must be in xxx.xxx.xxx.xxx format
For the data given below in table test:
IP
-----------------------------
000.000.000.001
000.000.001.002
000.000.002.001
000.000.018.001
000.001.001.002
try using
SELECT IP,
SUBSTRING(IP,1,3) AS IP1,
SUBSTRING(IP,5,3) AS IP2,
SUBSTRING(IP,9,3) AS IP3,
SUBSTRING(IP,13,3) AS IP4
FROM test
ORDER BY
SUBSTRING(IP,13,3) ASC,
SUBSTRING(IP,9,3) ASC,
SUBSTRING(IP,5,3) ASC,
SUBSTRING(IP,1,3) ASC
When you run this query the result will be:
ip IP1 IP2 IP3 IP4
-----------------------------------------------------------
000.000.000.001 000 000 000 001
000.000.002.001 000 000 002 001
000.000.018.001 000 000 018 001
000.000.001.002 000 000 001 002
000.001.001.002 000 001 001 002
Hope this helps.
CISCBrain
create table ipAddress
(
ipAddress nvarchar(20)
)
insert into ipAddress
select '0.0.18.1' union all
select '0.1.1.2' union all
select '0.0.0.1' union all
select '0.0.2.1'
go
select oct1, oct2, substring(ipAddress,1,charindex('.',ipAddress) - 1) + 0 as oct3,
substring(ipAddress,charindex('.',ipAddress) + 1,len(ipAddress)) + 0 as oct4
from
(
select oct1,
substring(ipAddress,1,charindex('.',ipAddress) - 1) + 0 as oct2,
substring(ipAddress,charindex('.',ipAddress) + 1, len(ipAddress)) as ipAddress
from
(
select substring(ipAddress,1,charindex('.',ipAddress) - 1) + 0 as oct1,
substring(ipAddress,charindex('.',ipAddress) + 1,len(ipAddress)) as ipAddress
from ipAddress
) as derivedTable1
) as derivedTable2
order by 1,2,3,4
go
drop table ipAddress
ScofferX
Or to split names
declare @name varchar(49)
select @name ='Bill Gates'
select PARSENAME(REPLACE(@name,' ','.'),2) as FirstName,
PARSENAME(REPLACE(@name,' ','.'),1) as LastName
Denis the SQL Menace
http://sqlservercode.blogspot.com/Rajesh G
Funny you should ask such a question. This is exactly what my blog from last night was about. A value stored in a varchar column with more than one distinct part of the same value (I called it a multi purpose character column). Any time you need to deal with one part of a value as different than the other, in this case for a sort, you need to rethink your storage. In this case, there are two good ways to store ipAddresses, as 1 bigint or 4 tinyint values. Check this article for a more complete reference: http://www.aspfaq.com/show.asp id=2450
Ah, but I still love SQL tricks. What I did to solve this was to peel the onion and do a substring for the first octet, then the "rest" of the string. Then I put that in a derived table, and did it again, and then again for the last one.
You probably could use a CTE to do this recursively, but since all ipAddresses (until ipv6 gets popular) are 4 parts, then this is a fine enough way to do this without using a function or procedure, as you requested
create table ipAddress
(
ipaddress nvarchar(20)
)
insert into ipAddress
select '0.0.18.1'
union all
select '0.1.1.2'
union all
select '0.0.0.1'
go
select oct1, oct2, substring(ipAddress,1,charindex('.',ipaddress) - 1) as oct3,
substring(ipAddress,charindex('.',ipaddress) + 1,len(ipAddress)) as oct4
from (select oct1, substring(ipAddress,1,charindex('.',ipaddress) - 1) as oct2,
substring(ipAddress,charindex('.',ipaddress) + 1,len(ipAddress)) as ipaddress
from (
select substring(ipAddress,1,charindex('.',ipaddress) - 1) as oct1,
substring(ipAddress,charindex('.',ipaddress) + 1,len(ipAddress)) as ipaddress
from ipAddress) as derivedTable1) as derivedTable2
order by 1,2,3,4
go
drop table ipAddress
no1cyf
jquevedog
_cham
You have to cast the parts to integer. The parsename value will simply be the text of the number, and sorting is from left to right so 1 is lower than 2 in this case. Look again at Steve's reply:
PARSENAME is well-suited for this:
select ipAddress
from netComputers
order by
CAST(PARSENAME(ipAddress,4) AS INT),
CAST(PARSENAME(ipAddress,3) AS INT),
CAST(PARSENAME(ipAddress,2) AS INT),
CAST(PARSENAME(ipAddress,1) AS INT)
-- Steve Kass
-- Drew University
peter_akerstrom
Will Perry
You converted your data to numeric format. When you use this select statement, you are sorting numeric data.
Select ipAddress from netComputers order by cast( replace(ipaddress,'.','') as numeric(12)) asc
Try using:
Select ipAddreaa from netComputers Order by ipAdddress Asc
Vaibhav2007
rikimaruXP
You can use PARSENAME in a lot of situations, for example this one, getting all the data up until the minus sign
CREATE TABLE #Test (
SomeField VARCHAR(49))
INSERT INTO #Test
VALUES ('aaa-bbbbb')
INSERT INTO #Test
VALUES ('ppppp-bbbbb')
INSERT INTO #Test
VALUES ('zzzz-xxxxx')
--using PARSENAME
SELECT PARSENAME(REPLACE(SomeField,'-','.'),2)
FROM #Test
--using LEFT and CHARINDEX
SELECT LEFT(SomeField,CHARINDEX('-',SomeField) - 1)
FROM #Test
--using LEFT and PATINDEX
SELECT LEFT(SomeField,PATINDEX('%-%',SomeField) - 1)
FROM #Test
--using CASE SUBSTRING and LEFT
SELECT CASE SUBSTRING(SomeField,4,1)
WHEN '-' THEN LEFT(SomeField,3)
ELSE LEFT(SomeField,4)
END
FROM #Test
--clean up
DROP TABLE #Test
fredkarm
It's been around since 6.x sometime I believe.
Very handy for some creative usage of period-delimited strings (like sorting ip-addresses)
=;o)
/Kenneth
Big Ticket
I try this
select * from(
select
'0.0.18.1' as IpAddress union allselect
'0.1.1.2' union allselect
'0.0.2.1' union allselect
'0.0.0.1' ) zorder
by parsename(ipaddress,1),parsename
(ipaddress,2),parsename
(ipaddress,3),parsename
(ipaddress,4);The result is
0.0.0.1
0.0.18.1
0.0.2.1
0.1.1.2
But I would expect the following instead.
0.0.0.1
0.0.2.1
0.0.18.1
0.1.1.2
Do I miss anything