Author |
Topic |
ferchen
Starting Member
5 Posts |
Posted - 2009-04-16 : 07:50:17
|
Hi all,thanks in advance for reading and helping.I have a table with an nvarchar(50) filed, the data contains text and/or numbers, when I'm trying to sort the data with I get wrong order, some of the rows with text(some contain numbers) appears before the rows with numbers, then all of the rows with numbers, and then the rest of the rows with text(some contain numbers). I tried to cast it to varbinary and I think it explains the problem; The sort I get is for some reason converted to varbinary and the being sorted.I expect a dictionary sort.Again, thanks for your help,Dani. |
|
LoztInSpace
Aged Yak Warrior
940 Posts |
Posted - 2009-04-16 : 09:08:34
|
You're going to have to provide examples, but SQL Server will be doing the right thing. Mixing numbers & text is going to cause these issues and you probably will have to redesign. Maybe use isnumeric() but usually this will suck too. |
|
|
ferchen
Starting Member
5 Posts |
Posted - 2009-04-16 : 09:40:46
|
Hi,examples are very simple, as I described:I have to metion that it's hebrew text so they are not the same exaples as below:1. ber 3562. bez 8963. 7304. 7505. 7536. abf7. acg8. df 7 e9. dz 910. ertetc.It's like "divided" to 3 sections and every section is sorted correctly. |
|
|
LoztInSpace
Aged Yak Warrior
940 Posts |
Posted - 2009-04-16 : 10:11:09
|
So you are saying that your data is Row followed by "."Some textspaceSome more textspacemore textWhen there are missing columns, how do you know which is which? e.g. row 3 - is the 730 column 2, 3 or 4?Can you explain how you think your example should be sorted and why? |
|
|
ferchen
Starting Member
5 Posts |
Posted - 2009-04-16 : 12:37:04
|
Hi,I expect the data to be dictionary sorted:3. 7304. 7505. 7536. abf7. acg1. ber 3562. bez 8968. df 7 e9. dz 910. ertor numbers last thanks. |
|
|
LoztInSpace
Aged Yak Warrior
940 Posts |
Posted - 2009-04-17 : 03:28:25
|
Your example shows numbers last!I'm confused.maybe this will get you 'numbers last' but I'm still not sure what you're after.ORDER BY case when col < 'A' then 'ZZZZ'+colelse col end; |
|
|
madhivanan
Premature Yak Congratulator
22864 Posts |
Posted - 2009-04-17 : 03:45:25
|
Numbers lastselect data from( select 'test' as data union all select '345' union all select 'as345' union all select 'b5' union all select 'f5' union all select 'd445' union all select '65' ) as torder by case when data not like '%[^0-9]%' then data*1 else 1 end, data MadhivananFailing to plan is Planning to fail |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2009-04-17 : 03:56:06
|
[code]DECLARE @Sample TABLE ( ID INT, Data VARCHAR(20), ExpectedOrder INT )INSERT @SampleSELECT 3, '730', 1 UNION ALLSELECT 4, '750', 2 UNION ALLSELECT 5, '753', 3 UNION ALLSELECT 6, 'abf', 4 UNION ALLSELECT 7, 'acg', 5 UNION ALLSELECT 1, 'ber 356', 6 UNION ALLSELECT 2, 'bez 896', 7 UNION ALLSELECT 8, 'df 7 e', 8 UNION ALLSELECT 9, 'dz 9', 9 UNION ALLSELECT 10, 'ert', 10SELECT ID, Data, ExpectedOrderFROM @SampleORDER BY Data[/code] E 12°55'05.63"N 56°04'39.26" |
|
|
Arnold Fribble
Yak-finder General
1961 Posts |
Posted - 2009-04-17 : 08:08:08
|
Since the example given doesn't demonstrate the problem, and the real data has a mixture of Hebrew letters (RTL) and 'Arabic' numerals (LTR), I think the problem has more to do with order within the rows than between them.Does this data show the sort of problem you are having? It looks to me like a plausible row order. (sorry if the Hebrew words are nonsense!)SELECT LTRIM(RTRIM(REPLACE(prefix + ' ' + word + ' ' + suffix, ' ', ' '))) AS sFROM ( SELECT CAST(N'' AS nvarchar(100)) AS word UNION ALL SELECT NCHAR(1488) + NCHAR(1460) + NCHAR(1501) UNION ALL SELECT NCHAR(1513) + NCHAR(1464) + NCHAR(1473) + NCHAR(1488) + NCHAR(1463) + NCHAR(1500) UNION ALL SELECT NCHAR(1512) + NCHAR(1460) + NCHAR(1488) + NCHAR(1513) + NCHAR(1473) + NCHAR(1493) + NCHAR(1465) + NCHAR(1503) UNION ALL SELECT NCHAR(1489) + NCHAR(1461) + NCHAR(1468) + NCHAR(1503) UNION ALL SELECT NCHAR(1496) + NCHAR(1493) + NCHAR(1465) + NCHAR(1489) UNION ALL SELECT NCHAR(1490) + NCHAR(1463) + NCHAR(1468) + NCHAR(1490) ) AS WCROSS JOIN ( SELECT CAST(N'' AS nvarchar(100)) AS prefix UNION ALL SELECT N'11119' UNION ALL SELECT N'2229' UNION ALL SELECT N'339' UNION ALL SELECT N'49' ) AS PCROSS JOIN ( SELECT CAST(N'' AS nvarchar(100)) AS suffix UNION ALL SELECT N'55559' UNION ALL SELECT N'6669' UNION ALL SELECT N'779' UNION ALL SELECT N'89' ) AS SORDER BY s |
|
|
ferchen
Starting Member
5 Posts |
Posted - 2009-04-19 : 03:51:16
|
Hi all,thanks for your help, but I see I missexplained the problem; The problem is a bad order between the rows.The problem is shown within Arnolds message.Thanks in advance.Dani. |
|
|
Arnold Fribble
Yak-finder General
1961 Posts |
Posted - 2009-04-19 : 08:48:25
|
quote: Originally posted by ferchen The problem is shown within Arnolds message.
SQL Team forums tends to mangle non-Latin text, so I'll extend my query to generate the a second string, but with the Hebrew word translated into English (well, hopefully: I'm relying on the examples in http://en.wikipedia.org/wiki/Hebrew_alphabet to be correct).I've made a few less interesting changes so the data types of the output columns aren't too long.SELECT s_englishFROM (SELECT LTRIM(RTRIM(LTRIM(RTRIM(prefix + ' ' + word)) + ' ' + suffix)) AS s, LTRIM(RTRIM(LTRIM(RTRIM(prefix + ' ' + english_word)) + ' ' + suffix)) AS s_english, LTRIM(RTRIM(LTRIM(RTRIM(prefix + ' ' + CASE WHEN english_word = N'' THEN N'' ELSE NCHAR(0x202E) + english_word + NCHAR(0x202C) END)) + ' ' + suffix)) AS s_english_rtlFROM ( SELECT CAST(N'' AS nvarchar(8)) AS word, CAST(N'' AS nvarchar(8)) AS english_word UNION ALL SELECT NCHAR(1488) + NCHAR(1460) + NCHAR(1501), 'if' UNION ALL SELECT NCHAR(1513) + NCHAR(1464) + NCHAR(1473) + NCHAR(1488) + NCHAR(1463) + NCHAR(1500), 'asked' UNION ALL SELECT NCHAR(1512) + NCHAR(1460) + NCHAR(1488) + NCHAR(1513) + NCHAR(1473) + NCHAR(1493) + NCHAR(1465) + NCHAR(1503), 'first' UNION ALL SELECT NCHAR(1489) + NCHAR(1461) + NCHAR(1468) + NCHAR(1503), 'son' UNION ALL SELECT NCHAR(1496) + NCHAR(1493) + NCHAR(1465) + NCHAR(1489), 'good' UNION ALL SELECT NCHAR(1490) + NCHAR(1463) + NCHAR(1468) + NCHAR(1490), 'roof' ) AS WCROSS JOIN ( SELECT CAST(N'' AS nvarchar(5)) AS prefix UNION ALL SELECT N'11119' UNION ALL SELECT N'2229' UNION ALL SELECT N'339' UNION ALL SELECT N'49' ) AS PCROSS JOIN ( SELECT CAST(N'' AS nvarchar(5)) AS suffix UNION ALL SELECT N'55559' UNION ALL SELECT N'6669' UNION ALL SELECT N'779' UNION ALL SELECT N'89' ) AS S) AS AORDER BY s The result I get has s_english column in this order, which looks ok to me (bearing in mind that the rows are in the order of the string containing the Hebrew words).quote: s_english--------------------1111911119 5555911119 666911119 77911119 8911119 if11119 if 5555911119 if 666911119 if 77911119 if 8911119 son11119 son 5555911119 son 666911119 son 77911119 son 8911119 roof11119 roof 5555911119 roof 666911119 roof 77911119 roof 8911119 good11119 good 5555911119 good 666911119 good 77911119 good 8911119 first11119 first 5555911119 first 666911119 first 77911119 first 8911119 asked11119 asked 5555911119 asked 666911119 asked 77911119 asked 8922292229 555592229 66692229 7792229 892229 if2229 if 555592229 if 66692229 if 7792229 if 892229 son2229 son 555592229 son 66692229 son 7792229 son 892229 roof2229 roof 555592229 roof 66692229 roof 7792229 roof 892229 good2229 good 555592229 good 66692229 good 7792229 good 892229 first2229 first 555592229 first 66692229 first 7792229 first 892229 asked2229 asked 555592229 asked 66692229 asked 7792229 asked 89339339 55559339 6669339 779339 89339 if339 if 55559339 if 6669339 if 779339 if 89339 son339 son 55559339 son 6669339 son 779339 son 89339 roof339 roof 55559339 roof 6669339 roof 779339 roof 89339 good339 good 55559339 good 6669339 good 779339 good 89339 first339 first 55559339 first 6669339 first 779339 first 89339 asked339 asked 55559339 asked 6669339 asked 779339 asked 894949 5555949 666949 77949 8949 if49 if 5555949 if 666949 if 77949 if 8949 son49 son 5555949 son 666949 son 77949 son 8949 roof49 roof 5555949 roof 666949 roof 77949 roof 8949 good49 good 5555949 good 666949 good 77949 good 8949 first49 first 5555949 first 666949 first 77949 first 8949 asked49 asked 5555949 asked 666949 asked 77949 asked 8955559666977989ifif 55559if 6669if 779if 89sonson 55559son 6669son 779son 89roofroof 55559roof 6669roof 779roof 89goodgood 55559good 6669good 779good 89firstfirst 55559first 6669first 779first 89askedasked 55559asked 6669asked 779asked 89(175 row(s) affected)
So in what way does s look like it's in the wrong order?If you're trying to assess the order by looking at the strings in column s displayed through a sophisticated bidirectional text rendering algorithm, then it may look confusing. In the above query, try selecting s instead of s_english at the outermost level and comparing the result you get in SSMS in text mode and grid mode.In SSMS 2005 the grid result view displays a glyph for each code point in the string in strict left-to-right order, whereas the text result view uses a bidirectional renderer. With the text result try moving the cursor through the lines of s, particularly a line that contains both a prefix numeric, a word and a suffix numeric. You should find (if the text view is defaulting to left-to-right) that the line containing, "339 WORD 55559" is rendered like "339 55559 DROW", but that the cursor follows the string order rather than the visual order.So why is the suffix number appearing to the left of the Hebrew word? In short it's the interaction between strongly right-to-left text (the Hebrew) being followed by weakly left-to-right text (the number).You can get almost the same effect with the output for english words by inserting a Unicode RLO before the word and a PDF (pop directional formatting) after: that's what's in the s_english_rtl column. |
|
|
ferchen
Starting Member
5 Posts |
Posted - 2009-04-20 : 10:02:17
|
Hi Arnold,thanks for your reply, I'm still trying to understand it -:)Dani. |
|
|
p_shripal
Starting Member
2 Posts |
Posted - 2009-09-09 : 04:18:59
|
quote: Originally posted by madhivanan Numbers lastselect data from( select 'test' as data union all select '345' union all select 'as345' union all select 'b5' union all select 'f5' union all select 'd445' union all select '65' ) as torder by case when data not like '%[^0-9]%' then data*1 else 1 end, data MadhivananFailing to plan is Planning to fail
Shripal |
|
|
p_shripal
Starting Member
2 Posts |
Posted - 2009-09-09 : 04:20:35
|
Could you let me know query for numbers first for your below post.quote: Originally posted by madhivanan Numbers lastselect data from( select 'test' as data union all select '345' union all select 'as345' union all select 'b5' union all select 'f5' union all select 'd445' union all select '65' ) as torder by case when data not like '%[^0-9]%' then data*1 else 1 end, data MadhivananFailing to plan is Planning to fail
Shripal |
|
|
madhivanan
Premature Yak Congratulator
22864 Posts |
Posted - 2009-09-09 : 05:33:59
|
quote: Originally posted by p_shripal Could you let me know query for numbers first for your below post.quote: Originally posted by madhivanan Numbers lastselect data from( select 'test' as data union all select '345' union all select 'as345' union all select 'b5' union all select 'f5' union all select 'd445' union all select '65' ) as torder by case when data not like '%[^0-9]%' then data*1 else 1 end, data MadhivananFailing to plan is Planning to fail
Shripal
Not sure if this works for all set of dataselect data from( select 'test' as data union all select '345' union all select 'as345' union all select 'b5' union all select 'f5' union all select 'd445' union all select '65' ) as torder by case when data like '%[^0-9]%' then data else '1' end, len(data) MadhivananFailing to plan is Planning to fail |
|
|
|