I have a column of type varchar that stores many different numbers. Say for example there are 3 rows: 17.95, 199.95 and 139.95.How can i sort that field as numbers in mysql
Quickest, simplest? use * 1
select *
from tbl
order by number_as_char * 1
The other reasons for using * 1 are that it can
survive some horrendous mishaps with underflow (reduced decimal precision when choosing what to cast to)
works (and ignores) columns of purely non-numeric data
strips numeric portions of alphanumeric data, such as 123A, 124A, 125A
If you need to sort a char column containing text AND numbers then you can do this.
tbl contains: 2,10,a,c,d,b,4,3
select * from tbl order by number_as_char * 1 asc, number_as_char asc
expected output: 2,3,4,10,a,b,c,d
If you don't add the second order by argument only numbers will be sorted - text actually gets ignored.
Use a CAST or a CONVERT function.
This approach is helpful when sorting text as numbers:
SELECT `my_field`
FROM `my_table`
ORDER BY `my_field` + 0;
Found the solution on http://crodrigues.com/trick-mysql-order-string-as-number/.
Pad the string with leading zeroes:
ORDER BY LPAD(`column`,<max length of string>,"0")
If you really have to you can do this if your source data is compatible:
SELECT column FROM table ORDER BY CAST(column AS DECIMAL(10,2))
It's not going to be very fast for large data sets though. If you can you should change the schema to use DECIMAL in the first place though. Then it can be properly indexed for better performance.
Related
I have a column(char) with values between A and Z
I only want to select the records where the char is >= 'C'
Can anyone help me with this?
I tried >= 'C' but this didn't work. Also I couldn't find anything about this on the internet. So I thought it's a good question to ask.
You can use the ascii value for comparison.
select * from tablename where ascii(colname) >= ascii('C')
here is another method.
SELECT SUBSTRING_INDEX(YourColumn,'c',-1) FROM Yourtable;
Strings can be compared in MySQL with regular comparison operators, so this should work:
SELECT * FROM table WHERE col >= 'C'
Do note that the exact sort order (mainly case sensitivity) for strings depends on your characterset collation. Maybe that is the reason why it didn't work for you.
You can also use ASCII() function, which returns the character value of a single character, and compare those:
SELECT * FROM table WHERE ASCII(col) >= ASCII('C')
Note that this only works for single byte characters. For multi byte characters you must use ORD() instead of ASCII().
Yet another way is to use STRCMP() which compares two strings (again, using the sort order of your characterset collation) and returns 0 if the strings are the same, -1 if the first argument is smaller than the second, and 1 otherwise.
SELECT * FROM table WHERE STRCMP(col, 'C') >= 0
I am having column named rating in the mysql database table with multiple values from 1+,2+,................9+,10+,12+. when i am sorting this column with query
select * from tbl_app order by rating desc
I am getting 9+ as highest value, can any one tell me how to get 12+ as highest value
SELECT rating,SUBSTR(rating,1,LENGTH(rating)-1) FROM tbl_app ORDER BY CAST(SUBSTR(rating,1,LENGTH(rating)-1) as SIGNED) DESC;
if the last char is always a '+',the sql above will work.
what have you kept the datatype of the column rating ? If you have kept it varchar or text then this query will not work for sorting values as per descending order.
Probably the easiest thing to do in MySQL is cast those odd looking strings to numbers:
order by cast(rating as unsigned) desc
-- or less explicitly
order by rating + 0 desc
Both of those casts will stop trying to convert the string to a number when they hit the + so you'll get them sorted numerically.
Simply removing the plus signs from the strings will still leave you with strings and '10' < '2' is just as true for strings as '10+' < '2+'. That's actually your whole problem: you're storing numbers as decorated strings when you should be storing them as integers and adding the + decorations when you display them. You really should fix your schema to make sense instead of adding ugly hacks to work around your schema's strange ideas.
try this :
select convert(replace(rating,'+',' '),unsigned integer) as x from tab order by x desc
sql_fiddle_demo
I want to display my cnumber in ascending order that is 1111111,2222,33333,4444,etc from the sql statement below.
SELECT
*
FROM
BIBLEBOOK
INNER JOIN
CHAPTER ON (BIBLEBOOK.BIBLEBOOK_Id=CHAPTER.BIBLEBOOK_Id)
INNER JOIN
VERS ON(CHAPTER.CHAPTER_Id=VERS.CHAPTER_Id)
WHERE
BIBLEBOOK.bnumber='2'
ORDER BY
cnumber ASC;*
But when i ran the sql result is
111111...10101010....111111...12121212....131313....22222222
how can i display the result like 1..2..3..4..5..6..
You can force a numerical sorting when converting your text data type to a numeric one. Use an explicit or this implicit cast
ORDER BY cnumber * 1 ASC
Your didn't include any DDLs to describe your tables, but it seems as though your cnumber is defined as a VARCHAR column, and thus is sorted lexicographically.
If it indeed only contains NUMERIC data and is always used as such, it might be a good idea to alter the column's datatype.
If you cannot do that, you can always explicitly cast it in your query so it's sorting numerically.
SELECT *
FROM BIBLEBOOK
INNER JOIN CHAPTER ON (BIBLEBOOK.BIBLEBOOK_Id=CHAPTER.BIBLEBOOK_Id)
INNER JOIN VERS ON(CHAPTER.CHAPTER_Id=VERS.CHAPTER_Id)
WHERE BIBLEBOOK.bnumber='2'
ORDER BY CAST (cnumber AS NUMERIC) ASC;
Looks like your cnumber is set to be text instead of numeric. Try using CONVERT function to force the ordering happen using standard number comparison instead of text one:
ORDER BY
CONVERT(cnumber, INTEGER) ASC;*
But I would start from considering your column data type change. Why is it set to be text when it handles numeric data on the first place?
I have a mysql database with a field "order_number" set as an INT on the odd occasion the order number would need to have a trailing r eg 2100r obviously INT will only accept numbers and would sort the number correctly ASC or DESC if I use VARCHAR to overcome this restriction it will correctly accept the trailing r character but will not sort the numbers in numerical order correctly, is there a way INT option can be forced to accept a character?
You need to store your account ids as character strings if any of them contain letters. But you can order them correctly as long as the letters are always suffixes. This works whether or not your AccountID values have leading spaces.
SELECT *
FROM Account
ORDER BY CAST(AccountID as UNSIGNED INTEGER), AccountID
This will order numerically, and then deal with any equal numbers by ordering lexically.
http://sqlfiddle.com/#!2/a16bf/8/0
If you wanted the "r" orders to be shown before their unadorned friends with the same number, you could do this:
SELECT *
FROM Account
ORDER BY CAST(AccountID as UNSIGNED INTEGER), AccountID DESC
you can use CAST function in MySQL but it's a good practice to store order_number as int using typecasting before inserting new data in table.
SELECT CAST(int_col AS CHAR);
SELECT CAST(char_col AS unsigned INTEGER);
No, there is no such option.
You should probably use a VARCHAR column for the order number and a separate column (possibly INT) just for sorting; populate the helper column based on what the order number is when inserting and updating rows.
Try to convert string to number using this way (number_string * 1), e.g. -
SELECT * FROM table ORDER BY column * 1;
No , Not possible. As #Jon said, there is no other options to force an INT field to keep VARCHAR data.
I have a field number of type varchar. Even though it is of type varchar, it stores integer values with optional leading zeros. A sort orders them lexicographically ("42" comes before "9"). How can I order by numeric values ("9" to come before "42")?
Currently I use the query:
SELECT * FROM table ORDER BY number ASC
Try this
SELECT * FROM table_name ORDER BY CAST(field_name as SIGNED INTEGER) ASC
There are a few ways to do this:
Store them as numeric values rather than strings. You've already discounted that as you want to keep strings like 00100 intact with the leading zeros.
Order by the strings cast as numeric. This will work but be aware that it's a performance killer for decent sized databases. Per-row functions don't really scale well.
Add a third column which is the numeric equivalent of the string and index on that. Then use an insert/update trigger to ensure it's set correctly whenever the string column changes.
Since the vast majority of databases are read far more often than written, this third option above amortises the cost of the calculation (done at insert/update) over all selects. Your selects will be blindingly fast since they use the numeric column to order (and no per-row functions).
Your inserts and updates will be slower but that's the price you pay and, to be honest, it's well worth paying.
The use of the trigger maintains the ACID properties of the table since the two columns are kept in step. And it's a well-known idiom that you can usually trade off space for time in most performance optimisations.
We've used this "trick" in many situations, such as storing lower-cased versions of surnames alongside the originals (instead of using something like tolower), lengths of identifying strings to find all users with 7-character ones (instead of using len) and so on.
Keep in mind that it's okay to revert from third normal form for performance provided you understand (and mitigate) the consequences.
Actually i've found something interesting:
SELECT * FROM mytable ORDER BY LPAD(LOWER(mycol), 10,0) DESC
This allows you to order the field like:
1
2
3
10
A
A1
B2
10A
111
SELECT * FROM table ORDER BY number + 0
Trick I just learned. Add '+0' to the varchar field order clause:
SELECT * FROM table ORDER BY number+0 ASC
I now see this answer above. I am wondering if this is typecasting the field and an integer. I have not compared performance. Working great.
For a table with values like Er353, ER 280, ER 30, ER36
default sort will give
ER280
ER30
ER353
ER36
SELECT fieldname, SUBSTRING(fieldname, 1, 2) AS bcd,
CONVERT(SUBSTRING(fieldname, 3, 9), UNSIGNED INTEGER) AS num
FROM table_name
ORDER BY bcd, num;
the results will be in this order
ER30
ER36
ER280
ER353
you can get order by according to your requirement my using following sql query
SELECT * FROM mytable ORDER BY ABS(mycol)
given a column username containing VARCHAR's like these:
username1
username10
username100
one could do:
SELECT username,
CONVERT(REPLACE(username, 'username', ''), UNSIGNED INTEGER) AS N
FROM users u
WHERE username LIKE 'username%'
ORDER BY N;
it is not cheap, but does the job.
SELECT * FROM table ORDER BY number ASC
Should display what you want it to display.. looks like you're sorting it by id or number is not defined as integer at the moment.
MySQL ORDER BY Sorting alphanumeric on correct order
example:
SELECT `alphanumericCol` FROM `tableName` ORDER BY
SUBSTR(`alphanumericCol` FROM 1 FOR 1),
LPAD(lower(`alphanumericCol`), 10,0) ASC
output:
0
1
2
11
21
100
101
102
104
S-104A
S-105
S-107
S-111
Another option to keep numerics at a top, then order by alpha.
IF(name + 0, name + 0, 9999999), name
Rough and ready: order by 1*field_name