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.
Author |
Topic |
malawneh
Starting Member
24 Posts |
Posted - 2006-12-19 : 11:06:43
|
The logic should work so that the field will be sorted like the following example.123Rm. 4Room 56101112202122Rm. 24rm 25alpha roombeta roomzeta roomThis is an example of the user input in expected output order. This is user entered and is not limited to int data. Hoe do I go about reaching this efficiently?Michael Alawneh, DBA |
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2006-12-19 : 11:12:51
|
The #1 thing you need to do in this situation is always be sure that ALL possibilities are represented in your sample data. People might spend hours writing a solution that works for the situations you present, but then suddenly we learn that "room one" needs to sort as if it were "room 1", and so on. So, that's the first order of business -- you must assure us that as we present solutions to help you, you will not be giving us a "moving target" by adding in new possibilities as you go. this happens WAAAY to often around here .... now, the long term solution, if the sorting of this data is important, is to enforce proper data types going forward. If we help you parse this column into a numeric value, you must comply by storing the numeric value in a true numeric column, which will be updated/maintained going forward, and by which further sorting and indexes and all that can be done. If the data is important enough that it needs to sort a certain way, then it needs to be stored a certain way as well. - Jeff |
 |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2006-12-19 : 11:30:45
|
[code]declare @t table (data varchar(100))insert @tselect '1' union allselect '10' union allselect '11' union allselect '12' union allselect '2' union allselect '20' union allselect '21' union allselect '22' union allselect '3' union allselect '6' union allselect 'alpha room' union allselect 'beta room' union allselect 'c12 room' union allselect 'rm 25' union allselect 'Rm. 24' union allselect 'Rm. 4' union allselect 'Room 5' union allselect 'zeta room'select t.datafrom ( select w.p1, w.data, patindex('%[^0-9]%', substring(w.data, w.p1, 8000)) p2 from ( select patindex('%[0-9]%', data) p1, data from @t ) w ) torder by case when t.p1 > 0 and t.p2 = 0 then cast(substring(t.data, t.p1, 8000) as int) when t.p1 > 0 and t.p2 > 0 then cast(substring(t.data, t.p1, t.p2 - t.p1 + 1) as int) else 2147483647 end[/code]Peter LarssonHelsingborg, Sweden |
 |
|
malawneh
Starting Member
24 Posts |
Posted - 2006-12-19 : 11:37:23
|
This is a varchar column and it will remain so because the developers do not want to provide the end users with another field to enter the potentialy numeric values.The rule for the sort order is if there is a numeric value anywhere in the field strip it out and use it for the order by, if the field has no numeric value sort based on the alpha sort. The above data in the samlple set is actual data through user entry. Regardless of spelling all we realy care about is the numeric portion first then the alpha sort takes over.Michael Alawneh, DBA |
 |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2006-12-19 : 11:44:31
|
Oh, man... Why do I keep to bother?Peter LarssonHelsingborg, Sweden |
 |
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2006-12-19 : 12:41:27
|
quote: Originally posted by malawneh This is a varchar column and it will remain so because the developers do not want to provide the end users with another field to enter the potentialy numeric values.The rule for the sort order is if there is a numeric value anywhere in the field strip it out and use it for the order by, if the field has no numeric value sort based on the alpha sort. The above data in the samlple set is actual data through user entry. Regardless of spelling all we realy care about is the numeric portion first then the alpha sort takes over.Michael Alawneh, DBA
You're the DBA, right? Then you explain to them that this is not how databases work. You need something called data integrity. If the numeric value has a meaning, if data needs to be sorted by it, then it needs to be stored in the database properly, potentially indexed as well. If the user enters a string via the UI and it needs to be parsed, it SHOULD BE PARSED AT THE CLIENT AT THE POINT OF ENTRY and only valid data should be stored in your database. The client application is much, much, much more equiped to do string processing/parsing rather than a relational database ! And doing it once, at the time of entry, it much, much more efficient than doing it over and over by the RDBMS each time the database is queried.Never confuse the UI with the database layer -- two different things. You should never store data in a certain manner because the UI presents it that way. If the developers feel it is the database's job to parse strings into numeric tokens, then it is time to get some new developers ......- Jeff |
 |
|
AndrewMurphy
Master Smack Fu Yak Hacker
2916 Posts |
Posted - 2006-12-19 : 12:46:32
|
"If the developers feel it is the database's job to parse strings into numeric tokens, then it is time to get some new developers ......"...easier way to get the message acrosss...ask the developers to come up with a solution!!!!!....using SQL....That'll cure them of their flexibility!! |
 |
|
malawneh
Starting Member
24 Posts |
Posted - 2006-12-19 : 13:18:50
|
I have a solution for this but it is slow. I need to speed it up. The code readds as follows.CLOSE ClassRoomADECursorDEALLOCATE ClassRoomADECursorDeclare @Count int , @Len Varchar(20)declare SortCur cursor for select ClassRoomAbbr from @TempOutputClassroomADEopen SortCurfetch next from SortCur into @Lenwhile @@FETCH_STATUS = 0 begin set @Count=0 while @Count < Len(@Len) begin Set @Count = @Count+1 if isnumeric(substring(@Len,@Count,1))=1 break else continue end update @TempOutputClassroomADE set Sort = case when isnumeric (Right(@Len,1))= 1 then substring(@Len,@Count,Len(@Len)-(@Count-1)) else @Len endwhere ClassRoomAbbr= @Lenfetch next from SortCur into @LenEndclose SortCurdeallocate SortCurupdate @TempOutputClassroomADE set [Count] = cast(sort as int) where isnumeric(Sort)=1update @TempOutputClassroomADE set [Count] = (Select max([Count])+1 from @TempOutputClassroomADE) where isnumeric(Sort)=0update @TempOutputClassroomADE set [Count] = (select max([Count])+2 from @TempOutputClassroomADE) where ClassRoomAbbr='ALL'SELECT ClassRoomAbbr , IsNull(Need, '') AS Need , IsNull(Time,'') AS Time , CurrentPeriod , AdjustmentFactor , Adjusted FROM @TempOutputClassroomADEORDER BY [Count],ClassRoomAbbrIs there another way, or can someone see where I can improve the effiency of this?Michael Alawneh, DBA |
 |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2006-12-19 : 13:22:42
|
Yes, I posted one to you at 12/19/2006 : 11:30:45, almost two hours ago...Peter LarssonHelsingborg, Sweden |
 |
|
malawneh
Starting Member
24 Posts |
Posted - 2006-12-19 : 14:31:50
|
here is the output I get when using the query from 'PESO'. It works great when only considering the numeric value. but it should also sort secondly on the char value.data --------------------------------------------------------------------------------------------------- #1RM 1Roland Room 1D Classroom11C11Roland Room 1C1C1C1C1C2C2C2C2C2D Classroom2#2#3C3C3C3C4#4C5#11#11Rm 121Rm 221Rm 221Rm 228Rm 1001RM 1112TestDCSPS Class Room(39 row(s) affected)so the output if only taking the ("1") values into consideration should sort as follows.data --------------------------------------------------------------------------------------------------- #111C1C1C1C1C1D Classroom1RM 1Roland Room 1Roland Room 1Thank you all for your help.Michael Alawneh, DBA |
 |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2006-12-19 : 14:37:54
|
I thought you should be able to add "data" to the sort order.The only thing differ between this query and the one above, is the code at bottom highlighted in red.declare @t table (data varchar(100))insert @tselect '#1' union allselect 'RM 1' union allselect 'Roland Room 1' union allselect 'D Classroom1' union allselect '1' union allselect 'C1' union allselect '1' union allselect 'Roland Room 1' union allselect 'C1' union allselect 'C1' union allselect 'C1' union allselect 'C1' union allselect 'C2' union allselect 'C2' union allselect 'C2' union allselect 'C2' union allselect 'C2' union allselect 'D Classroom2' union allselect '#2' union allselect '#3' union allselect 'C3' union allselect 'C3' union allselect 'C3' union allselect 'C4' union allselect '#4' union allselect 'C5' union allselect '#11' union allselect '#11' union allselect 'Rm 121' union allselect 'Rm 221' union allselect 'Rm 221' union allselect 'Rm 228' union allselect 'Rm 1001' union allselect 'RM 1112' union allselect 'Test'select t.datafrom ( select w.p1, w.data, patindex('%[^0-9]%', substring(w.data, w.p1, 8000)) p2 from ( select patindex('%[0-9]%', data) p1, data from @t ) w ) torder by case when t.p1 > 0 and t.p2 = 0 then cast(substring(t.data, t.p1, 8000) as int) when t.p1 > 0 and t.p2 > 0 then cast(substring(t.data, t.p1, t.p2 - t.p1 + 1) as int) else 2147483647 end, data Peter LarssonHelsingborg, Sweden |
 |
|
malawneh
Starting Member
24 Posts |
Posted - 2006-12-19 : 14:48:13
|
Thank you so much it was a complete oversight on my part. I have been strugling with this for some time now. My brain is fried. Once again thank you.Michael Alawneh, DBA |
 |
|
|
|
|
|
|