August 31, 2005 at 1:38 pm
I am running SQL Server 2000 and need to perform a sort on an alphanumeric field that does not have a consistent pattern for the values contained in the column to be sorted. For example, the column name is FILENUM varchar(30). Given a set of filenumbers:
1dd
1
1x4
1cc2
1110-345-720a3
11
380-41-3a
10
should be sorted as:
1
1cc2
1dd
1x4
10
11
380-41-3a
1110-345-720a3
I am having difficulty finding a solution to sort the data as requested. Any assistance would be greatly appreciated.
thanks,
Tracy
August 31, 2005 at 1:46 pm
This would allow you to sort based on each character.
order by substring(filenum,1,1), substring(filenum,2,1)...
What is the logic behind having 380-41-3a appear before 1110-345-720a3
and 1x4 before 10?
Could you strip out all the letters and symbols and then sort by the resulting number?
Michelle
September 1, 2005 at 7:38 am
Michelle-
The logic behind having 380-41-3a appear before 1110-345-720a3 is that the integer 380 comes before 1110. I cannot strip out the letters as they would want them to be used for sorting also, for example 380-41-3a would come before 380-41-3b. Their logic for having 1x4 before 10 is that the integer 1 comes before 10. They basically want me to sort the numerics in the filenumber as an Integer and the letters as alpha. It seems I would have to break each down into a substring and sort based upon that. However, not all filenumbers contain a letter and the filenumbers vary in length. Hope this makes sense. I'm not even sure if what they are asking is doable.
thanks,
Tracy
September 1, 2005 at 7:46 am
Someone with some smarts might be a better help. I can't come up with a way to do what they are asking.
Michelle
September 1, 2005 at 8:29 am
This is not dealing with the Alpha characters well, (I threw this together), but it might help someone smarter than I to get their brains working:
CREATE TABLE #Sort( [Value] varchar(100))
INSERT INTO #Sort VALUES( '1dd')
INSERT INTO #Sort VALUES( '1')
INSERT INTO #Sort VALUES( '1x4')
INSERT INTO #Sort VALUES( '1cc2')
INSERT INTO #Sort VALUES( '1110-345-720a3')
INSERT INTO #Sort VALUES( '11')
INSERT INTO #Sort VALUES( '380-41-3a')
INSERT INTO #Sort VALUES( '10')
SELECT *
FROM #Sort
ORDER BY CASE
WHEN ASCII( SUBSTRING( [Value], CHARINDEX( '1234567890', [Value], 1),
(CHARINDEX( '-', [Value], 1) ))) BETWEEN CHAR(48) AND CHAR(57)
THEN CONVERT( integer, SUBSTRING( [Value], CHARINDEX( '1234567890', [Value], 1),
(CHARINDEX( '-', [Value], 1) )))
ELSE SUBSTRING( [Value], CHARINDEX( '1234567890', [Value], 1), (CHARINDEX( '-', [Value], 1) ))
END
DROP TABLE #Sort
[Note: it is the second part of the substring I am having difficulty, (trying to figure out how to include numerous choices for the CHARINDEX or trying to choose anything that is not a number...]
I wasn't born stupid - I had to study.
September 1, 2005 at 9:03 am
This is a working sol IF you don't mind the speed...
The idea is to padd all numbers from your strings to a certain len ( a max len that should cover all lengths of your numbers I used 10 in this case)
----- START FUNCTION-----
CREATE FUNCTION [dbo].[nmbPadd]
(@mystr varchar(20))
RETURNS varchar(4000)
AS
BEGIN
declare @StartNmb int
declare @StopNmb int
declare @pos int
declare @isNumb bit
declare @myLen int
declare @rez varchar(4000)
if (@myStr is null or len(@myStr)=0) return ''
set @rez=''
set @myLen=len(@mystr)
set @isNumb=0
set @pos=1
while (@pos<=@myLen)
begin
if (charindex(substring(@mystr,@pos,1),'0123456789')>0)
begin
--check to see if the prev char was numeric
if (@isNumb=1)
begin
set @StopNmb=@StopNmb+1
end
else
begin--prev char was NOT numeric
set @StartNmb=@pos
set @StopNmb=1
end
set @isNumb=1
end
else--our current char is not numeric
begin
--check to see if the prev char was numeric
if (@isNumb=1)
begin
--10 is max number of digitis that a number can have
set @rez=@rez+replicate('0',10-@StopNmb)+substring(@myStr,@StartNmb,@StopNmb+1)
end
else
begin--prev char was NOT numeric
set @rez=@rez+substring(@mystr,@pos,1)
end
set @isNumb=0
end
set @pos=@pos+1
end
if (@isNumb=1)
set @rez=@rez+replicate('0',10-@StopNmb)+substring(@myStr,@StartNmb,@StopNmb)
return @rez
END
---- END FUNCTION------
GO
declare @t table (sort varchar(20))
insert into @t
select '1dd' union all
select '1' union all
select '1x4' union all
select '1cc2' union all
select '1110-345-720a3' union all
select '11' union all
select '380-41-3a' union all
select '10'
select sort from @t
order by [dbo].[nmbPadd](sort)
Vasc
September 1, 2005 at 9:24 am
I get an error: Server: Msg 156, Level 15, State 1, Procedure nmbPadd, Line 72
Incorrect syntax near the keyword 'declare'.
I wasn't born stupid - I had to study.
September 1, 2005 at 9:32 am
Strange ... the function has only 65 lines ... Did you copy paste correct?
Vasc
September 1, 2005 at 9:40 am
The GO was missing. Did you just add that along with the comments?
Thanks (great solution...). I was hoping to be able to do this without having to loop through all of the values...
I wasn't born stupid - I had to study.
September 1, 2005 at 9:45 am
ya I added the GO
But I didn't inted the first time to post a QA batch to create the function and run the query...
Like I said it is UGLY but is working...
Dunno how to do a clean solution for this ... maybe another aproach
Vasc
September 1, 2005 at 1:55 pm
A big THANK YOU to Vasc!
This solution works pefectly for us.
thanks!
Tracy
September 2, 2005 at 9:27 am
Vasc,
DECLARE @sort TABLE ( [Value] varchar(100))
INSERT INTO @sort VALUES( '1dd')
INSERT INTO @sort VALUES( '1')
INSERT INTO @sort VALUES( '1x4')
INSERT INTO @sort VALUES( '1cc2')
INSERT INTO @sort VALUES( '1110-345-720a3')
INSERT INTO @sort VALUES( '11')
INSERT INTO @sort VALUES( '380-41-3a')
INSERT INTO @sort VALUES( '10')
SELECT
Value
FROM @sort
ORDER BY
CONVERT(INT, CASE
WHEN ISNUMERIC(VALUE)= 1 THEN Value
ELSE LEFT(Value, PATINDEX('%[^1234567890]%',Value)-1) END),
PATINDEX('%[abcdefghijklmnopqrstuvwxyz-]%',Value)-1 ASC,
Value ASC
Just as a FYI the ^ means NOT - so it is looking for any non-numeric value.
Hope this gives someone another choice sometime down the road.
Tim Blum
Senior Manager, Outsourced Data Services
Learn2Live at Ureach.com
Viewing 13 posts - 1 through 12 (of 12 total)
You must be logged in to reply to this topic. Login to reply