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
 SQL Server Development (2000)
 order by string with multi decimals?

Author  Topic 

homerjay
Starting Member

7 Posts

Posted - 2004-08-23 : 06:50:18
hi

i have a table with a multiple columns, one if which (FLOAD_LEVEL VARCHAR2(2000)) i wish to order by.

how do i order by so that my result is:

1
1.2
1.3
1.4
1.4.1
1.4.2
1.5
1.6
1.6.1
1.6.1.1
1.6.1.2
1.6.2
1.7

and not

1
1.2
1.3
1.4
1.5
1.6
1.7
1.4.1
1.4.2
1.6.1
1.6.2
1.6.1.1
1.6.1.2

many thanks!

SamC
White Water Yakist

3467 Posts

Posted - 2004-08-23 : 07:01:58
ORDER BY REPLACE(Column, '.', '')
Go to Top of Page

SamC
White Water Yakist

3467 Posts

Posted - 2004-08-23 : 07:06:53
Whops! Maybe converting to integers would be better. Are there more than 4 digits.

ORDER BY CAST(LEFT(REPLACE(Column, '.', '')+'0000', 4) AS INT)
Go to Top of Page

homerjay
Starting Member

7 Posts

Posted - 2004-08-23 : 07:08:45
oooh so close

now i get

1
10
100
100.1
100.1.1
100.1.1.2
100.2
2
20
200.1
201

thanks for the reply
Go to Top of Page

homerjay
Starting Member

7 Posts

Posted - 2004-08-23 : 07:09:40
damn, that reply was for the 1s aswer, will try the 2nd idea...
Go to Top of Page

homerjay
Starting Member

7 Posts

Posted - 2004-08-23 : 07:12:14
sorry, yea there are more that 4 digits, infinate number...

its a structure code to determine levels and sublevel jobs...

Go to Top of Page

homerjay
Starting Member

7 Posts

Posted - 2004-08-23 : 07:24:05
hmmm, still not quite right

returns:
12
120
12.1
121
12.10
12.1.1
12.1.2
12.2
122
etc

but need to be:
12
12.1
12.1.1
12.1.2
12.2
13....119
120
121
122
Go to Top of Page

AndrewMurphy
Master Smack Fu Yak Hacker

2916 Posts

Posted - 2004-08-23 : 07:24:35
get your data to look like.....

001.000.000.000
001.002.000.000
001.003.000.000
001.004.000.000
001.004.001.000
001.004.002.000
001.005.000.000
001.006.000.000
001.006.001.000
001.006.001.001
001.006.001.002
001.006.002.000
001.007.000.000


and you will have no problem sorting...

you need to add/pad all records to make sure the structures have same number of characters.
Go to Top of Page

homerjay
Starting Member

7 Posts

Posted - 2004-08-23 : 07:28:13
cheers, will have a play and let ya know
Go to Top of Page

SamC
White Water Yakist

3467 Posts

Posted - 2004-08-23 : 08:03:10
Andrew is right: the CONVERT could create a float, just add a decimal to the left (easier) and sort on 0.xxxxxx

quote:
sorry, yea there are more that 4 digits, infinate number...


There could be too many digits which would surpass the accuracy of floating point. Maybe this should remain a character sort:

-- Add characters '0' to the right and make all strings the same length
SELECT MyCol
FROM MyTable M
CROSS JOIN (
SELECT MAX(LEN(MyCol)) As MaxLen
FROM MyTable ) L
ORDER BY LEFT(MyCol + REPLICATE('0', MaxLen), MaxLen)
Go to Top of Page

homerjay
Starting Member

7 Posts

Posted - 2004-08-23 : 08:34:36
done, done and done...

thanks all!
Go to Top of Page

derrickleggett
Pointy Haired Yak DBA

4184 Posts

Posted - 2004-08-23 : 08:39:04

Here's a longer way to do it. lol



DECLARE @sort TABLE(point VARCHAR(55))

INSERT @sort(point)
SELECT '1' UNION ALL
SELECT '1.2' UNION ALL
SELECT '1.3' UNION ALL
SELECT '1.4' UNION ALL
SELECT '1.5' UNION ALL
SELECT '1.6' UNION ALL
SELECT '1.7' UNION ALL
SELECT '1.4.1' UNION ALL
SELECT '1.4.2' UNION ALL
SELECT '1.6.1' UNION ALL
SELECT '1.6.2' UNION ALL
SELECT '1.6.1.1' UNION ALL
SELECT '1.6.1.2'

SELECT point FROM @sort

SELECT CHARINDEX('.',point,CHARINDEX('.',point)+1) FROM @sort
SELECT LEFT(point,CHARINDEX('.',point)) FROM @sort
SELECT point
FROM @sort
ORDER BY
CASE
WHEN CHARINDEX('.',point,CHARINDEX('.',point)+1) = 0 THEN CAST(point AS DECIMAL(9,5))
ELSE CAST(LEFT(point,CHARINDEX('.',point)) + REPLACE(RIGHT(point,LEN(point)-CHARINDEX('.',point)),'.','') AS DECIMAL(9,5)) END


MeanOldDBA
derrickleggett@hotmail.com

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

SamC
White Water Yakist

3467 Posts

Posted - 2004-08-23 : 08:48:35
quote:
done, done and done...

Sounds like (is it Homer or Jay?) is getting tired. Next post he'll be saying: Stop! Stop! Stop!

Derrick, what's the difference declaring @Table and #Table ?

Sam
Go to Top of Page

derrickleggett
Pointy Haired Yak DBA

4184 Posts

Posted - 2004-08-23 : 08:51:01
@Table is a table variable (held in memory instead of tempdb, but only good if you have less than 10k rows really), whereas #Table is a temp table.

From Books Online:


table
A special data type that can be used to store a result set for later processing. Its primary use is for temporary storage of a set of rows, which are to be returned as the result set of a table-valued function.

Syntax


Note Use DECLARE @local_variable to declare variables of type table.


table_type_definition ::=
TABLE ( { column_definition | table_constraint } [ ,...n ] )

column_definition ::=
column_name scalar_data_type
[ COLLATE collation_definition ]
[ [ DEFAULT constant_expression ] | IDENTITY [ ( seed , increment ) ] ]
[ ROWGUIDCOL ]
[ column_constraint ] [ ...n ]

column_constraint ::=
{ [ NULL | NOT NULL ]
| [ PRIMARY KEY | UNIQUE ]
| CHECK ( logical_expression )
}

table_constraint ::=
{ { PRIMARY KEY | UNIQUE } ( column_name [ ,...n ] )
| CHECK ( search_condition )
}

Arguments
table_type_definition

Is the same subset of information used to define a table in CREATE TABLE. The table declaration includes column definitions, names, data types, and constraints. The only constraint types allowed are PRIMARY KEY, UNIQUE KEY, and NULL. A user-defined data type cannot be used as a column scalar data type.

For more information about the syntax, see CREATE TABLE, CREATE FUNCTION, and DECLARE @local_variable.

collation_definition

Is the collation of the column consisting of a Microsoft® Windows™ locale and a comparison style, a Windows locale and the binary notation, or a Microsoft SQL Server™ collation.

Remarks
Functions and variables can be declared to be of type table. table variables can be used in functions, stored procedures, and batches.

Use table variables instead of temporary tables, whenever possible. table variables provide the following benefits:

A table variable behaves like a local variable. It has a well-defined scope, which is the function, stored procedure, or batch in which it is declared.
Within its scope, a table variable may be used like a regular table. It may be applied anywhere a table or table expression is used in SELECT, INSERT, UPDATE, and DELETE statements. However, table may not be used in the following statements:

INSERT INTO table_variable EXEC stored_procedure

SELECT select_list INTO table_variable statements.

table variables are cleaned up automatically at the end of the function, stored procedure, or batch in which they are defined.

CHECK constraints, DEFAULT values and computed columns in the table type declaration cannot call user-defined functions.


table variables used in stored procedures result in fewer recompilations of the stored procedures than when temporary tables are used.


Transactions involving table variables last only for the duration of an update on the table variable. Thus, table variables require less locking and logging resources.
Assignment operation between table variables is not supported. In addition, because table variables have limited scope and are not part of the persistent database, they are not impacted by transaction rollbacks.


MeanOldDBA
derrickleggett@hotmail.com

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

SamC
White Water Yakist

3467 Posts

Posted - 2004-08-23 : 08:53:13
Here's another potential problem:

Should

1.1.5
appear before or after
10.5

Removing the dots will place the second item first. Maybe removing the dots is a bad idea? Should these columns be sorted by each integer separated by the dot?
Go to Top of Page

derrickleggett
Pointy Haired Yak DBA

4184 Posts

Posted - 2004-08-23 : 08:58:35
Mine takes that into account Sam. In mine 10.5 will appear after 1.1.5 .

MeanOldDBA
derrickleggett@hotmail.com

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

SamC
White Water Yakist

3467 Posts

Posted - 2004-08-23 : 10:07:48
Yep, then yours is not longer, it's right.

I can't easily unscramble the CHARINDEX nests. Does your query take the ORDER BY to any number of decimal places ?

Go to Top of Page

derrickleggett
Pointy Haired Yak DBA

4184 Posts

Posted - 2004-08-23 : 10:35:46
I set it as DECIMAL(9,5). If you need more, just change it in both places. Is this for outlining?

MeanOldDBA
derrickleggett@hotmail.com

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

Seventhnight
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2004-08-23 : 10:58:05
quote:
Originally posted by AndrewMurphy

get your data to look like.....

001.000.000.000
001.002.000.000
001.003.000.000
001.004.000.000
001.004.001.000
001.004.002.000
001.005.000.000
001.006.000.000
001.006.001.000
001.006.001.001
001.006.001.002
001.006.002.000
001.007.000.000


and you will have no problem sorting...

you need to add/pad all records to make sure the structures have same number of characters.



Andrew got it right... except they don't have to be the same length, so the following should work as well:

001
001.002
001.003
001.004
001.004.001
001.004.002
001.005
001.006
001.006.001
001.006.001.001
001.006.001.002
001.006.002
001.007

Try the following


declare @myTable table (unPadded varchar(1000), padded varchar(1000))
Insert Into @myTable
Select '1', null
Union All Select '1.2', null
Union All Select '1.3', null
Union All Select '1.6.1.2', null
Union All Select '10.1.1', null
Union All Select '1.5', null
Union All Select '1.6.1.1', null
Union All Select '1.6', null
Union All Select '1.6.2', null
Union All Select '1.7', null
Union All Select '10.1', null
Union All Select '1.4.1', null
Union All Select '10.1.2', null
Union All Select '1.4', null
Union All Select '1.4.2', null
Union All Select '1.6.1', null
Union All Select '100.1', null


Select * From @myTable

Declare @pad varchar(10)
Set @pad = '000'

While exists(Select 1 From @myTable Where charindex('.',unPadded)>0)
Begin
Update @myTable
Set
unPadded = right(unPadded,len(unPadded)-charindex('.',unPadded)),
padded = isnull(padded+'.','') + right(@pad + left(unPadded,charindex('.',unPadded)-1),3)
From @myTable
Where charindex('.',unPadded)>0
End

Update @myTable
Set
unPadded = null,
padded = isnull(padded+'.','') + right(@pad + isnull(unPadded,''),3)
From @myTable

Select * From @myTable Order By padded






Corey
Go to Top of Page

derrickleggett
Pointy Haired Yak DBA

4184 Posts

Posted - 2004-08-23 : 14:50:08
Why would you do that though? I'm just curious. Just make is a real number and sort it.

MeanOldDBA
derrickleggett@hotmail.com

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

Seventhnight
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2004-08-23 : 15:07:56
Wouldn't that limit the number of branches he could make??
If 200 is one of his branches then that requires a least 3 characters per branch

So thats what? 12 branches. If he needs to beyond that then what? or what if 200 isn't the largest, say 2000 then thats 4 which leaves 9 branches...

I just like it as its a little less limiting.

Corey
Go to Top of Page
    Next Page

- Advertisement -