Is there a possibility to obtain letters (like A,B) instead of numbers (1,2) e.g. as a result of Dense_Rank function call(in MS Sql) ?
相关问题
- SQL join to get the cartesian product of 2 columns
- sql execution latency when assign to a variable
- Difference between Types.INTEGER and Types.NULL in
- What is the best way to cache a table from a (SQL)
- php PDO::FETCH_ASSOC doesnt detect select after ba
hint: try this in your SQL Enterprise manager
a full solution, for ranks up to 17,500 (or three letters, up to ZZZ) is:
Not a direct answer - but if somebody has a alphabet conversion requirement with 3 characters, following is what I am doing.
Another approach - get next character code (it is alpha-numeric result). If you pass '00A' it will return '00B'
I used this as a basis for my function to convert integers to base26 character strings
You can convert the values to an offset base-26 with a UDF:
EDIT: Corrected function.
Sample values:
At ErikE's suggestion I ran a quick performance test on my notebook. 1,000,000 iterations of the UDF vs. the XML solution:
The UDF was a little more than 3 times faster.
Try this:
Just be aware that when you get to 27 (past
Z
), things are going to get interesting, and not useful.If you wanted to start doubling up letters, as in
... X, Y, Z, AA, AB, AC, AD ...
then it's going to get a bit trickier. This works in all versions of SQL Server. TheSELECT
clauses are just an alternate to a CASE statement (and 2 characters shorter, each).See a Live Demo at SQL Fiddle
(Demo for SQL 2008 and up, note that I use
Dense_Rank()
to simulate a series of numbers)This will work from
A
toZZZZZ
, representing the values1
to12356630
. The reason for all the craziness above instead of a more simple expression is becauseA
doesn't simply represent0
, here. Before each threshold when the sequence kicks over to the next letterA
added to the front, there is in effect a hidden, blank, digit--but it's not used again. So 5 letters long is not 26^5 combinations, it's 26 + 26^2 + 26^3 + 26^4 + 26^5!It took some REAL tinkering to get this code working right... I hope you or someone appreciates it! This can easily be extended to more letters just by adding another letter-generating expression with the right values.
Since it appears I'm now square in the middle of a proof-of-manliness match, I did some performance testing. A
WHILE
loop is to me not a great way to compare performance because my query is designed to run against an entire set of rows at once. It doesn't make sense to me to run it a million times against one row (basically forcing it into virtual-UDF land) when it can be run once against a million rows, which is the use case scenario given by the OP for performing this against a large rowset. So here's the script to test against 1,000,000 rows (test script requires SQL Server 2005 and up).And the results:
Original Query
I initially did this a "fun" way by generating 1 row per letter and pivot-concatenating using XML, but while it was indeed fun, it proved to be slow. Here is that version for posterity (SQL 2005 and up required for the
Dense_Rank
, but will work in SQL 2000 for just converting numbers to letters):See a Live Demo at SQL Fiddle