Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 Transact-SQL (2000)
 Returning results in Numeric Order

Author  Topic 

josethegeek
Starting Member

45 Posts

Posted - 2004-03-05 : 19:00:16
Hello,
I hope someone can help me out, I'm sure alot of you have had this problem.

What I want to do is return is products and order them by numbers.

For example, when I query SQL Server, I get the results like this..
Stylus 50
Stylus 6000
Stylus 73

Want I want returned is
Stylus 50
Stylus 73
Stylus 6000

Could some one please help me with this problem?

Thanks a bunch,
Jose

ehorn
Master Smack Fu Yak Hacker

1632 Posts

Posted - 2004-03-05 : 19:07:29
[code]create table test (value varchar(20))

insert into test
select 'Stylus 50' union all
select 'Stylus 6000' union all
select 'Stylus 73'

select *
from test
order by convert(int,substring(value,charindex(' ',value,1),len(value)))

drop table test
[/code]
Go to Top of Page

josethegeek
Starting Member

45 Posts

Posted - 2004-03-05 : 19:19:47
quote:
Originally posted by ehorn

create table test (value varchar(20))

insert into test
select 'Stylus 50' union all
select 'Stylus 6000' union all
select 'Stylus 73'

select *
from test
order by convert(int,substring(value,charindex(' ',value,1),len(value)))

drop table test


Go to Top of Page

josethegeek
Starting Member

45 Posts

Posted - 2004-03-05 : 19:22:18
quote:
Originally posted by ehorn

create table test (value varchar(20))

insert into test
select 'Stylus 50' union all
select 'Stylus 6000' union all
select 'Stylus 73'

select *
from test
order by convert(int,substring(value,charindex(' ',value,1),len(value)))

drop table test




Ehorn,
Thank You for that really really fast response :). Would this break if it wasn't just numbers. It seems like it converts the results to datatype of int.

What if I have a Stylus InkjetC, Stylus Fax123, etc?

Thanks Again,
Jose
Go to Top of Page

ehorn
Master Smack Fu Yak Hacker

1632 Posts

Posted - 2004-03-05 : 19:26:48
There are many ways to perform the order by. This particluar solution is based on your posted values. It trims the numbers off of the end, then converts them to integers. If you know your domain of results and desired sorting order, a solution can be derived. You will have to test this particlar solution to see if it will fit your needs. If it does not, you can provide a set of data that is more representative of your output and someone here can work up an order by statement to meet your needs.
Go to Top of Page

josethegeek
Starting Member

45 Posts

Posted - 2004-03-05 : 19:39:26
quote:
Originally posted by ehorn

There are many ways to perform the order by. This particluar solution is based on your posted values. It trims the numbers off of the end, then converts them to integers. If you know your domain of results and desired sorting order, a solution can be derived. You will have to test this particlar solution to see if it will fit your needs. If it does not, you can provide a set of data that is more representative of your output and someone here can work up an order by statement to meet your needs.



Ehorn,
Thanks again. Basically the database field is of type varchar(100). The values that get inserted into the table could be numbers or text. I would like to query the table and return the records in order, first by text(abc etc) then by numbers.

For Example let's say that we have these values in the table...
Fax Color 32
Stylus 3
Stylus 100
Stylus 4
Stylus Color 2
Stylus Color 400
Stylus Color 213

I would want something like this returned...
Fax Color 32
Stylus 4
Stylus 100
Stylus Color 2
Stylus Color 231

I hope I explained myself correctly. Thanks again.

Jose
Go to Top of Page

derrickleggett
Pointy Haired Yak DBA

4184 Posts

Posted - 2004-03-05 : 19:43:50
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[fnGENRemoveNonNumeric]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[fnGENRemoveNonNumeric]
GO

CREATE FUNCTION dbo.fnGENRemoveNonNumeric
--Name: fnGENRemoveNonNumeric
--Purpose: This function strips all non-numeric fields from a string.
--
--Format: dbo.fnGENRemoveNonNumeric('field')
--Example_1: SELECT dbo.fnGENRemoveNonNumeric(Address) FROM Customers
--Example_2: SELECT Address FROM Customers ORDER BY dbo.fnGENRemoveNonNumeric(Address)
--
--Action: Author: Date: Comments:
--------- ---------- --/--/---- ----------------------------------------
--Created Derrick Leggett 08/11/2003 Initial Development
--
(
@inputText VARCHAR(255)
)
RETURNS VARCHAR(255)
AS
BEGIN

--Declare needed values.
DECLARE
@prepText VARCHAR(255),
@i INT,
@char CHAR(1)

--Populate values to control the looping validation of text.
SELECT
@prepText = '',
@i = 1

--Loop through text to identify valid characters.
WHILE @i <= LEN(@inputText)
BEGIN

--Select the value of the string in position @i.
SELECT @char = (SELECT SUBSTRING(@inputText, @i, 1))

--Add next value to string. Can be 0-9.
IF CHARINDEX(@char, '0123456789') <> 0
SET @prepText = @prepText + @char

--Increment the string search to go to the next character.
SELECT @i = @i + 1
END

RETURN @prepText

END
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO



declare @values table(
value varchar(55))

insert @values(value)values('StylusLS')
insert @values(value)values('Stylus 50')
insert @values(value)values('Stylus 6000')
insert @values(value)values('Stylus 73')
insert @values(value)values('Too poor to buy a printer')
insert @values(value)values('Stylus')

select value from @values

select value from @values order by value + dbo.fnGENRemoveNonNumeric(value)


Would be careful how I use this. :)

MeanOldDBA
derrickleggett@hotmail.com

When life gives you a lemon, fire the DBA.
Go to Top of Page

ehorn
Master Smack Fu Yak Hacker

1632 Posts

Posted - 2004-03-05 : 19:50:02
[code]select *
from test
order by
replace(value,reverse(left(reverse(value),charindex(' ',reverse(value),1))),''),
convert(int,ltrim(reverse(left(reverse(value),charindex(' ',reverse(value),1)))))
[/code]
Go to Top of Page

josethegeek
Starting Member

45 Posts

Posted - 2004-03-05 : 19:58:42
quote:
Originally posted by derrickleggett

SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[fnGENRemoveNonNumeric]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[fnGENRemoveNonNumeric]
GO

CREATE FUNCTION dbo.fnGENRemoveNonNumeric
--Name: fnGENRemoveNonNumeric
--Purpose: This function strips all non-numeric fields from a string.
--
--Format: dbo.fnGENRemoveNonNumeric('field')
--Example_1: SELECT dbo.fnGENRemoveNonNumeric(Address) FROM Customers
--Example_2: SELECT Address FROM Customers ORDER BY dbo.fnGENRemoveNonNumeric(Address)
--
--Action: Author: Date: Comments:
--------- ---------- --/--/---- ----------------------------------------
--Created Derrick Leggett 08/11/2003 Initial Development
--
(
@inputText VARCHAR(255)
)
RETURNS VARCHAR(255)
AS
BEGIN

--Declare needed values.
DECLARE
@prepText VARCHAR(255),
@i INT,
@char CHAR(1)

--Populate values to control the looping validation of text.
SELECT
@prepText = '',
@i = 1

--Loop through text to identify valid characters.
WHILE @i <= LEN(@inputText)
BEGIN

--Select the value of the string in position @i.
SELECT @char = (SELECT SUBSTRING(@inputText, @i, 1))

--Add next value to string. Can be 0-9.
IF CHARINDEX(@char, '0123456789') <> 0
SET @prepText = @prepText + @char

--Increment the string search to go to the next character.
SELECT @i = @i + 1
END

RETURN @prepText

END
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO



declare @values table(
value varchar(55))

insert @values(value)values('StylusLS')
insert @values(value)values('Stylus 50')
insert @values(value)values('Stylus 6000')
insert @values(value)values('Stylus 73')
insert @values(value)values('Too poor to buy a printer')
insert @values(value)values('Stylus')

select value from @values

select value from @values order by value + dbo.fnGENRemoveNonNumeric(value)


Would be careful how I use this. :)

MeanOldDBA
derrickleggett@hotmail.com

When life gives you a lemon, fire the DBA.



derrickleggett,
Thank You. I tried it, but it still gave me the records back in the order I previously had them.
Jose
Go to Top of Page

josethegeek
Starting Member

45 Posts

Posted - 2004-03-05 : 19:59:35
quote:
Originally posted by ehorn

select * 
from test
order by
replace(value,reverse(left(reverse(value),charindex(' ',reverse(value),1))),''),
convert(int,ltrim(reverse(left(reverse(value),charindex(' ',reverse(value),1)))))




Ehorn,
Thanks Again. I tried it, but it gave me a convertion error. It said it could not convert the record to a value of int.

Thanks Again,
Jose
Go to Top of Page

ehorn
Master Smack Fu Yak Hacker

1632 Posts

Posted - 2004-03-05 : 20:18:54
Yea, You must have some data like 'Stylus Color' or >= two word values with no numbers which are trying to be converted to ints. I will give it another try using a derived table:
create table test (value varchar(20))

insert into test
select 'Fax Color 32' union all
select 'Stylus 3' union all
select 'Stylus Color 2' union all
select 'Stylus Color 400' union all
select 'Stylus 100' union all
select 'Stylus Color' union all
select 'Stylus' union all
select 'fax123'

select value
from
(
select *
, case when isnumeric(left(reverse(value),charindex(' ',reverse(value),1))) = 1
then replace(value,reverse(left(reverse(value),charindex(' ',reverse(value),1))),'')
else value
end value_text

, case when isnumeric(left(reverse(value),charindex(' ',reverse(value),1))) = 1
then reverse(left(reverse(value),charindex(' ',reverse(value),1)))
else 0
end num

from test
) d
order by value_text, num

drop table test
Go to Top of Page

Lumbago
Norsk Yak Master

3271 Posts

Posted - 2004-03-07 : 08:45:26
What about this:
declare @test table (value varchar(20))

insert into @test
select 'Fax Color 32' union all select 'Stylus 3' union all
select 'Stylus Color 2' union all select 'Stylus Color 400' union all
select 'Stylus 100' union all select 'Stylus Color' union all
select 'Stylus' union all select 'fax123'

select value, SUBSTRING(value + '00000000000000000', 1, 20) AS NewValue
from @test
order by NewValue
Go to Top of Page

jsmith8858
Dr. Cross Join

7423 Posts

Posted - 2004-03-07 : 10:52:29
"Model number" should be a seperate column in your table. never combine different pieces of information into 1 column in your data design ... you can always concatenate different columns together very easily, and sort by the different columns, but it is not always possible or desirable to try to parse a column like this out into multiple values.

- Jeff
Go to Top of Page

ehorn
Master Smack Fu Yak Hacker

1632 Posts

Posted - 2004-03-07 : 10:53:56
Derrick, here is a set-based method for the function you provided:
--create tally table for the function

create table numbers ( n int primary key)
declare @n int ; set @n = 1
while @n <=255
begin
insert into numbers
select @n
set @n = @n + 1
end
GO

create function dbo.fn_remove_non_numeric (@value varchar(255))
returns varchar(255)
as
begin

declare @chars table (vc char(1), list varchar(255))

insert into @chars (vc)
select substring(@value,n,1)
from numbers
where n <=len(@value)
and substring(@value,n,1) like '[0-9]'

declare @list varchar(255)
select @list = ''

update @chars
set @list = list = @list + vc

return
(
select max(list)
from @chars
)
end
GO

declare @value varchar(255)
select @value = 'Some 111 value with num222eric 333data in 444 it'
select dbo.fn_remove_non_numeric(@value)

drop function dbo.fn_remove_non_numeric
Go to Top of Page

derrickleggett
Pointy Haired Yak DBA

4184 Posts

Posted - 2004-03-08 : 09:11:57
Kewl. Thanks.

MeanOldDBA
derrickleggett@hotmail.com

When life gives you a lemon, fire the DBA.
Go to Top of Page

josethegeek
Starting Member

45 Posts

Posted - 2004-03-08 : 12:16:20
quote:
Originally posted by jsmith8858

"Model number" should be a seperate column in your table. never combine different pieces of information into 1 column in your data design ... you can always concatenate different columns together very easily, and sort by the different columns, but it is not always possible or desirable to try to parse a column like this out into multiple values.

- Jeff



jsmith8858,
Well the model number is a type of varchar(100) because a model number can be a word, a number or a word with number. We don't have control of what the model number is.

Thanks.
Go to Top of Page

josethegeek
Starting Member

45 Posts

Posted - 2004-03-08 : 12:21:09
quote:
Originally posted by Lumbago

What about this:
declare @test table (value varchar(20))

insert into @test
select 'Fax Color 32' union all select 'Stylus 3' union all
select 'Stylus Color 2' union all select 'Stylus Color 400' union all
select 'Stylus 100' union all select 'Stylus Color' union all
select 'Stylus' union all select 'fax123'

select value, SUBSTRING(value + '00000000000000000', 1, 20) AS NewValue
from @test
order by NewValue




Lumbago,
Thanks for giving it a try, but I still keep getting the same results.

Jose
Go to Top of Page

josethegeek
Starting Member

45 Posts

Posted - 2004-03-08 : 12:24:25
quote:
Originally posted by ehorn

Derrick, here is a set-based method for the function you provided:
--create tally table for the function

create table numbers ( n int primary key)
declare @n int ; set @n = 1
while @n <=255
begin
insert into numbers
select @n
set @n = @n + 1
end
GO

create function dbo.fn_remove_non_numeric (@value varchar(255))
returns varchar(255)
as
begin

declare @chars table (vc char(1), list varchar(255))

insert into @chars (vc)
select substring(@value,n,1)
from numbers
where n <=len(@value)
and substring(@value,n,1) like '[0-9]'

declare @list varchar(255)
select @list = ''

update @chars
set @list = list = @list + vc

return
(
select max(list)
from @chars
)
end
GO

declare @value varchar(255)
select @value = 'Some 111 value with num222eric 333data in 444 it'
select dbo.fn_remove_non_numeric(@value)

drop function dbo.fn_remove_non_numeric




Ehorn,
Thanks, but I still have that problem. I want to order results by the way humans are used to ordering, not computers.

For example 23 should have precedence over 10987, but that is not the way SQL server returns the records when they are of datatype varchar, it works with int but since the data that is entered into this field varies we have to use varchar.

Thanks Again,
Jose
Go to Top of Page

Lumbago
Norsk Yak Master

3271 Posts

Posted - 2004-03-08 : 12:39:34
quote:
Lumbago,
Thanks for giving it a try, but I still keep getting the same results.

Jose
Yeah I always read these posts to fast so I keep missing some of the vital details. My suggestion only works for the "18, 19, 2, 20, 21"-problem...

--
Lumbago
"Real programmers don't document, if it was hard to write it should be hard to understand"
Go to Top of Page

ehorn
Master Smack Fu Yak Hacker

1632 Posts

Posted - 2004-03-08 : 12:40:43
Jose,

Sorry for the confusion, the function I provided was not intended for your situation. Did you try the derived table solution I psted earlier in this post??
Go to Top of Page

josethegeek
Starting Member

45 Posts

Posted - 2004-03-08 : 13:03:10
quote:
Originally posted by ehorn

Jose,

Sorry for the confusion, the function I provided was not intended for your situation. Did you try the derived table solution I psted earlier in this post??



Ehorn,
I did, but it still doesn't return the data back like I want it(1,2, 339, etc).

Thanks Again,
Jose
Go to Top of Page
    Next Page

- Advertisement -