views:

738

answers:

3

In SQLSERVER/MSSQL, here's the problem:

SELECT * from [Translation Color] order by [Language Code]

I want records ordered in alphabetical order starting by the 'I' letter.

Example of result:

'Ioren' 'Iumen' 'Tart' 'Arfen' 'Coldry'

I don't want to use union or more sql statements.. just try to catch it with an order by special clause.

I've tried with:

ORDER BY <field> REGEXP '^I' DESC

but it didn't work.

Any ideas?

+1  A: 

This should do it:

ORDER BY CASE WHEN SUBSTRING([Translation Color],1,1) = 'l' 
     THEN 1 ELSE 0 END DESC

EDIT:

Full answer for ordering completely starting at i, then looping back round to h is:

ORDER BY CASE WHEN ASCII(UPPER(SUBSTRING([Translation Color],1,1))) < 73 
         THEN ASCII(UPPER(SUBSTRING([Translation Color],1,1))) + 26
         ELSE ASCII(UPPER(SUBSTRING([Translation Color],1,1))) END ASC,       
         [Translation Color] ASC

Please note that this will affect performance on large tables.

ck
== gives error, but with one = it works! thank you
avastreg
Remember to check the performance is acceptable though, especially if you have or are likely to have a large dataset.
Neil Barnwell
Yeah sorry about that, am coding in C# at the mo, but I've edited it to be right.
ck
BTW - very clever solution - trés bien!
Neil Barnwell
Does it actually work?
Dog Ears
@Dog Ears: See [== gives error, but with one = it works! thank you – avastreg (49 mins ago)]
ck
I'm missing the point but don't you want the data to order like this..l m n o....g h i j k Does the selected answer do that?
Dog Ears
@Dog Ears, You are correct. The OP suggests that they need the ordering I-ZA-H. ck's answer doesn't deliver this, your answer and mine do. Note though that it's an I (i), not an l (L).
LukeH
@Dog Ears, Luke: Answer updated with full answer
ck
good work guys! :)
avastreg
+1  A: 

Alternatively is this any good:

select [Translation Color], 
  case when [Translation Color] < 'l' then 1
                     else 0 
                     end as Priority
from t1 
order by Priority, [Translation Color]

This will order it alphabeticly starting at 'l'

Edit This solution seems to work for me:

create table t1 ( c1 varchar(20) collate SQL_Latin1_General_Cp437_CI_AS)

then i populated with some test data then run this:

select c1 
from t1 
order by case when c1 >= 'l' then 0 else 1 end, c1
Dog Ears
+1: nice answer, very clean, but does use separate element in select statement
ck
My edit works perfectly but doesn't uses the order by clause.
Dog Ears
... *now* uses (not doesn't) the order by clause!
Dog Ears
+1  A: 
SELECT *
FROM [Translation Color]
ORDER BY
    CASE WHEN [Language Code] LIKE '[I-Zi-z]%' THEN 0 ELSE 1 END,
    [Language Code]
LukeH
+1: Nice answer, but LIKE clause could be quite slow on large data sets, but possible not as slow as mine :) (however I assume this is a small lookup table)
ck
@ck, The LIKE isn't ideal, but it should still be able to use any index on the [Language Code] column. I suspect that using SUBSTRING, ASCII, UPPER etc would necessitate a table scan.
LukeH
@ck, I agree that it's most likely a small lookup table. However, even if every drop of performance isn't vital, I think that my answer is more readable than all those string functions.
LukeH
You answer is indeed more readable. I like the fact there are three different answers to this question.
ck
I like this answer as I imagine it's more tolerant of different collations.
Dog Ears