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.
Related
i'm working with mysql in a nodejs web app. I don't understand why when I ask for some id (key) it gives me more than 1 result.
When I:
SELECT * FROM products WHERE id = 1;
This happens, I get 3 results, but I only want 1:
1, 001 and 0000001.
I just want the info of one product (id: 1 in this example)
How can I fix this?
ID type is varchar(20)
If I use LIKE instead of = my result changes:
SELECT * FROM products WHERE id LIKE 0000001;
I get the info of id = 1 instead 0000001. Don't know why.
Thanks
The WHERE clause of your query contains a comparison of a literal numeric value with a string (column id).
When it needs to compare values of different type, MySQL uses several rules to convert one or both of the values to a common type.
Some of the type conversion rules are not intuitive. The last rule is the only one that matches a comparison of an integer number with a string:
In all other cases, the arguments are compared as floating-point (real) numbers.
When they are converted to floating-point (real) numbers, 1 (integer), '1', '0001' and '0000001' are all equal.
In order to get an exact match the literal value you put in the query must have the same type as the column id (i.e string). The query should be:
SELECT * FROM products WHERE id = '1'
The problem is that you are looking by a varchar type using an integer cast.
Try to add quotes to the id parameter:
SELECT * FROM products WHERE id = '1';
If you want to add integer ids with with leading zeros, I recommend you to use the zerofill option:
https://dev.mysql.com/doc/refman/5.5/en/numeric-type-attributes.html
If you want to use use alphanumeric values then keeps the ID type as varchar, but remember to enclose the search param into quotes.
Numbers in MySQL (and the real world) don't have leading zeros. Strings do.
So, you just need to make the comparison using the right type:
SELECT *
FROM products
WHERE id = '1';
What happens with your original query is that the id is converted to a number. And '1', '001' and '0000001' are all converted to the same integer -- 1. Hence, all three pass the filter.
I am using simple order by clause to show products according to available quantity
Below is the query I am using:
SELECT * FROM productsinfo ORDER BY quantity desc
Query giving no error but sorting order is not correct.Anyone please tell me where I am wrong.
EDIT
Have checked my quentity clumn is varchar type.I am storing values in 1,215 10,456 format.
Might be your quantity column is varchar type so it's not sorting as numbers.Please check.
You need to cast it in integer type
Try below:
SELECT * FROM productsinfo ORDER BY CAST(quantity AS UNSIGNED ) desc
OR Use below trick.
SELECT * FROM productsinfo ORDER BY quantity+0 DESC
I think you define quantity as VarChar. Because if it's a Number (int, smallint, decimal,..) the order will be definitely correct.
SELECT *, CAST(quantity AS int) QuantityA
FROM productsinfo
ORDER BY QuantityA desc
You'll have to first remove the , from the value and turn the result into a number. Give this a try:
SELECT * FROM productsinfo
ORDER BY REPLACE(quantity, ',', '')+0 DESC
The exect answer is:-
for varchar data type it compares integert data from left to right that means it treat 100 less the the 11.
So thats why comparing and sorting on varchar data type for integer data is a bad choice.
Convert it to int using cast in a query or alter your table.
Is it possible to convert text into a number within MySQL query? I have a column with an identifier that consists a name and a number in the format of "name-number". The column has VARCHAR type. I want to sort the rows according to the number (rows with the same name) but the column is sorted according to do character order, i.e.
name-1
name-11
name-12
name-2
If I cut off the number, can I convert the 'varchar' number into the 'real' number and use it to sort the rows? I would like to obtain the following order.
name-1
name-2
name-11
name-12
I cannot represent the number as a separate column.
edited 2011-05-11 9:32
I have found the following solution ... ORDER BY column * 1. If the name will not contain any numbers is it safe to use that solution?
This should work:
SELECT field,CONVERT(SUBSTRING_INDEX(field,'-',-1),UNSIGNED INTEGER) AS num
FROM table
ORDER BY num;
You can use SUBSTRING and CONVERT:
SELECT stuff
FROM table
WHERE conditions
ORDER BY CONVERT(SUBSTRING(name_column, 6), SIGNED INTEGER);
Where name_column is the column with the "name-" values. The SUBSTRING removes everything up before the sixth character (i.e. the "name-" prefix) and then the CONVERT converts the left over to a real integer.
UPDATE: Given the changing circumstances in the comments (i.e. the prefix can be anything), you'll have to throw a LOCATE in the mix:
ORDER BY CONVERT(SUBSTRING(name_column, LOCATE('-', name_column) + 1), SIGNED INTEGER);
This of course assumes that the non-numeric prefix doesn't have any hyphens in it but the relevant comment says that:
name can be any sequence of letters
so that should be a safe assumption.
Simply use CAST,
CAST(column_name AS UNSIGNED)
The type for the cast result can be one of the following values:
BINARY[(N)]
CHAR[(N)]
DATE
DATETIME
DECIMAL[(M[,D])]
SIGNED [INTEGER]
TIME
UNSIGNED [INTEGER]
You can use CAST() to convert from string to int. e.g. SELECT CAST('123' AS INTEGER);
SELECT *, CAST(SUBSTRING_INDEX(field, '-', -1) AS UNSIGNED) as num FROM tableName ORDER BY num;
one simple way SELECT '123'+ 0
cast(REGEXP_REPLACE(NameNumber, '[^0-9]', '') as UNSIGNED)
To get number try with SUBSTRING_INDEX(field, '-', 1) then convert.
if your primary key is a string in a format like
ABC/EFG/EE/13/123(sequence number)
this sort of string can be easily used for sorting with the delimiter("/")
we can use the following query to order a table with this type of key
SELECT * FROM `TABLE_NAME` ORDER BY
CONVERT(REVERSE(SUBSTRING(REVERSE(`key_column_name`), 1, LOCATE('/', REVERSE(`key_column_name`)) - 1)) , UNSIGNED INTEGER) DESC
I found it easier to use regex_replace function to strip off all non numeric values from the field and then sort.
SELECT field , CONVERT(REGEXP_REPLACE(field,'[^0-9]',''),UNSIGNED) AS num FROM your_table ORDER BY num;
select
`a`.uuid,
concat('1',REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(`a`.uuid,'-',''),'b','11'),'c','12'),'d','13'),'e','14'),'f','15'),'a','10')),
A generic way to do :
SELECT * FROM your_table ORDER BY LENTH(your_column) ASC, your_column ASC
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.
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