Related
I have complex SQL-Statements with group_concat and i need sometimes to convert the value. So i use something like this (Its an example):
SELECT IF(1=1,CAST(TEST AS CHAR),CAST(TEST AS UNSIGNED))
FROM(
SELECT '40' as TEST
UNION
SELECT '5' as TEST
UNION
SELECT '60' as TEST
) as t1
ORDER BY TEST ASC;
Should return CHAR, returns CHAR.
SELECT IF(1=0,CAST(TEST AS CHAR),CAST(TEST AS UNSIGNED))
FROM(
SELECT '40' as TEST
UNION
SELECT '5' as TEST
UNION
SELECT '60' as TEST
) as t1
ORDER BY TEST ASC;
Should return UNSIGNED, returns CHAR
So the result of IF condition is always a CHAR and need to be CAST.
How i can resolve the problem?
MySQL tries to figure out the column type just by parsing the SQL, not based on runtime conditions like the way an IF() expression goes. While your example allows the result of the IF() to be determined before actually processing any rows, this is not true in general and MySQL doesn't perform this optimization.
It just sees that the IF() can return either UNSIGNED or CHAR, and figures out a common type that both can be converted to safely. This is CHAR.
This is explained in the documentation:
The default return type of IF() (which may matter when it is stored into a temporary table) is calculated as follows:
If expr2 or expr3 produce a string, the result is a string.
If expr2 and expr3 are both strings, the result is case-sensitive if either string is case sensitive.
If expr2 or expr3 produce a floating-point value, the result is a floating-point value.
If expr2 or expr3 produce an integer, the result is an integer.
Just asking if this is possible:
I have a mysql database 'data' and a column 'count' which contains numbers such as
3741
49215
345
4686794
I was wondering if there is a possibility to remove the last figure from each number in this column, so there will be these values:
374
4921
34
468679
(for 100,000 rows so i can't do it manually :) )
Thank you!
This will work if the field is numeric or string and is always > 0:
UPDATE `table` SET `count` = FLOOR(`count`/10)
Note single digit values will become 0
If some numbers are negative, it will not give the right answer and a substring approach like the other answers is better.
Use the MySQL SUBSTRING function to extract portion of a string. Use CHAR_LENGTH function to calculate the number of characters in the string.
SELECT
col,
SUBSTRING(col, 1, CHAR_LENGTH(col) - 1) AS col_trimme
FROM tbl
is the data type is string you can
update my_table
set my_column = substr(my_column, 1, length(my_column) -2)
if is an int you can cast
update my_table
set my_column = cast(substr(cats(my_column AS varchar(16)), 1, length(my_column AS varchar(16)) -1), AS INT)
This will work if the field is numeric or string:
UPDATE table SET count = SUBSTRING(count, 1, CHAR_LENGTH(count) - 1);
When I executed following query to find the country name by the ID, I accidentally passed a string that contained comma-separated values.
SELECT * FROM country WHERE id='6,AU,+61'
This query fetched that respective row.
When I tried casting this string into UNSIGNED using
SELECT CAST('6,AU,+61' AS UNSIGNED)
It returned 6, the first value.
When I tried integer values separated by comma (for eg: '7,8'), it also returned 7. So, it wasn't taking any values after the first comma.
In case of CAST('AU,+61' AS UNSIGNED), it returned zero.
Isn't '7,8' a string, so why is it not converting this into zero and taking first value instead?
MySql casts string to number by looking at the string from its left most char going right.
If the first char is a digit, it will iterate right until it reaches a non-digit char and will cast it to a number. if the string starts with a non-digit char it will cast to 0.
Thats why CAST('AU,+61' AS UNSIGNED) is 0
While CAST('7,8' AS UNSIGNED) is 7
However, The above is not documented specifically in the MySql Cast reference.
Although there are few examples over there and a specific line that implies such a behavior:
there are many different strings that may convert to the value 1, such as '1', ' 1', or '1a'.
However this can be validated with few simple tests:
SELECT CAST('a7' as UNSIGNED) as 'col_a7'; -- 0
SELECT CAST('7q6' as UNSIGNED) as 'col_7q6'; -- 7
SELECT CAST(' 7q6' as UNSIGNED) as 'col__7q6'; -- 7
SELECT CAST('1.4' as UNSIGNED) as 'col1.4'; -- 1
I might not be so clear in my description above, but these tests should clarify things.
I have a query where I have to extract some number fields from varchar column.
When i do some replace and substring in select statement and cast it to bigint everything works fine, but when I use this same cast in join it throws error
'Error converting data type varchar to bigint'.
How is this possible?
select CAST(
case when CHARINDEX('/',f.BML,1)>0
then substring(replace(replace(replace(replace(replace(replace(replace(replace(replace(f.BML,'A',''),'B',''),'C',''),'+',''),',',''),'S',''),'H',''),'P',''),'¸','') ,1,CHARINDEX('/',BML,1)-1)
else replace(replace(replace(replace(replace(replace(replace(replace(replace(f.BML,'A',''),'B',''),'C',''),'+',''),',',''),'S',''),'H',''),'P',''),'¸','')
end as bigint)
from TableN n join TableO o on
n.Id=o.Id
join TableF f on
f.OId=o.OId and
substring(cast(n.RJ as varchar(10)),1,3)=substring(CAST(f.MT AS varchar(10)),1,3) and
CAST(
case when CHARINDEX('/',f.BML,1)>0 then substring(replace(replace(replace(replace(replace(replace(replace(replace(replace(f.BML,'A',''),'B',''),'C',''),'+',''),',',''),'S',''),'H',''),'P',''),'¸','') ,1,CHARINDEX('/',f.BML,1)-1)
else replace(replace(replace(replace(replace(replace(replace(replace(replace(f.BML,'A',''),'B',''),'C',''),'+',''),',',''),'S',''),'H',''),'P',''),'¸','')
end as bigint) =n.mbr
order by n.Ident
As I indicated in my comment, there's no guarantee on the order in which conditions are assessed. So if you have:
f.OId=o.OId and
substring(cast(n.RJ as varchar(10)),1,3)=substring(CAST(f.MT AS varchar(10)),1,3) and
CAST(
case when CHARINDEX('/',f.BML,1)>0 then substring(replace(replace(replace(replace(replace(replace(replace(replace(replace(f.BML,'A',''),'B',''),'C',''),'+',''),',',''),'S',''),'H',''),'P',''),'¸','') ,1,CHARINDEX('/',f.BML,1)-1)
else replace(replace(replace(replace(replace(replace(replace(replace(replace(f.BML,'A',''),'B',''),'C',''),'+',''),',',''),'S',''),'H',''),'P',''),'¸','')
end as bigint) =n.mbr
And either f.OId=o.OId or substring(cast(n.RJ as varchar(10)),1,3)=substring(CAST(f.MT AS varchar(10)),1,3) should eliminate rows with values of BML that are not convertible to bigint, that's no guarantee that the conversion will not be attempted.
You can attempt to move the filters that should eliminate bad BML values into a subquery or CTE, but that's still no guarantee that the query optimizer won't push the conversion operator down into the subquery and still cause an error.
The only real way to deal with this (unfortunately) is to split the query into two pieces, eliminating unconvertible values in the first query, and placing the result of this query in a temp table/table variable. Then build the second half of the query using this temp 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