SQL query for sorting numeric fields - mysql

I have one column of the type VARCHAR which stores numbers like 10, 11, 16.5, 24, 43, 12, 100, etc.
I want to order these fields but it sorts like this:
10
11
12
16.5
100
24
43
And I'd like this result:
10
11
12
16.5
24
43
100
How can I do this?

VARCHAR is a string type, so it's ordering them alphabetically, which is the expected behavior. If possible you should change the column to a number type. If that's not possible you can cast the value to a number like so:
SELECT ... ORDER BY CAST(column_name AS DECIMAL)
However, this will impact your performance if you have a lot of rows in your database.

order by to_number(mycol)
this will of course give an error if one value is not numeric. which begs the question - why not make it a numeric column in the first place.

You want to cast the field to be a numeric value instead, so that MySQL will order it with a numeric comparison, rather than a string comparison.
SELECT your_column
FROM your_table
ORDER BY CAST(your_column AS DECIMAL) ASC
The above will work with negative numbers too, if you have any of those in your table.
Although if the field only contains numeric data, you really should be storing it as such, rather than as a varchar. Having a cast in your query will dramatically affect performance as you get more rows.

Just add zero to your field without any cast or convert:
order by 0+yourfield ASC

Related

MySQL STR_TO_DATE Problem while using this function

As title, I'm trying to convert a VARCHAR column in a DATE column, and data is populated in that format "DDMMYYYY" ex. XMAS is "25122022" and in this case the correct formula should be STR_TO_DATE(column, '%d%m%Y')Well, when I execute this query I get an error since in some cases I have values with a "missing" char, I mean, for example, "1012023" when the day is <10 the query fails, cause it checks for "01122023" instead.I could solve this easily by adding a 0 to all fields having length 7, but I'd like to make it more clean.Reading better the usage of STR_TO_DATE I noticed that I could replace %d with %e since the second choice should theorically consider days from 0 to 31 instead of 01 to 31.Unexpectedly the query didn't work and gave me the same erorr at the first instance of a length 7 string.Am I doing something wrong?Thanks in advance.
We can try left padding your date string with zero to a length of 8:
WITH yourTable AS (
SELECT '1012023' AS dt
)
SELECT STR_TO_DATE(LPAD(dt, 8, '0'), '%d%m%Y') AS dt_out -- 2023-01-01
FROM yourTable;
Demo

SUBSTRING_INDEX Not Warking in Mysql

I am trying to find max invoice:
SELECT IFNULL(MAX(SUBSTRING_INDEX(invoice,'I', -1)) + 1, 1) AS invoice
FROM sales
SQL Fiddle
When I run this SQL query, it can not count more than 10.
invoice
20221026P1I1
20221026P1I2
20221026P1I3
20221026P1I4
20221026P1I5
20221026P1I6
20221026P1I7
20221026P1I8
20221026P1I9
20221026P1I10
20221026P1I11
20221026P1I12
I am trying to find max invoice 12 + 1 = 13
Your use of SUBSTRING_INDEX() is correct, however you should cast the string value to a bona fide integer:
SELECT COALESCE(MAX(CAST(SUBSTRING_INDEX(invoice, 'I', -1) AS UNSIGNED)), 1) AS invoice
FROM sales;
The problem with trying to find the max of the text substrings themselves is that text numbers sort lexicographically, e.g.
1
10
11
2
23
But this isn't the behavior you want, you want the numeric maximum. Hence we should cast these substrings and then compare.
Side note: You could have avoided this problem entirely by maintaining a pure numeric invoice number column. You may want to change your table design to include such a column.

MySQL: Getting&assigning number from a column of strings

The table contains a column that contain strings. I would like to extract numbers from the string.
The code: http://sqlfiddle.com/#!9/2af45
Eg:
1 Day = 1
2 Day anytime = 2
7 Days = 7
SameDay = 1
As for string that does not contain any number, I would like to assign a number to it.
What I have in mind:
What will be the best solution such that the query will not affect the loading speed greatly on MySQL?
Additional challenge: If the number appears randomly in the string, is there any method/algorithm that can potentially pull the number?
E.g. every 2 day, promotion in 7 days
If the string starts with a number, you can simply CAST it to an UNSIGNED. Any text after the number is ignored
CAST("2 Day anytime" AS UNSIGNED);
CAST("20 fishes" AS UNSIGNED);
Any string that doesn't start will a number, will become 0. You can turn that into some other value with the combination of NULLIF and IFNULL.
IFNULL(NULLIF(CAST("SameDay" AS UNSIGNED), 0), 1);
You can create a new column with ALTER TABLE and than do an UPDATE query.
UPDATE foo (days_int)
SELECT IFNULL(NULLIF(CAST(days_string AS UNSIGNED), 0), 1)
FROM foo;
Note that the update and select is from the same table.

TINYTEXT Calculation in MYSQL

MYSQL Database:
I have a field in a Table Column1 contain the Price value, but declared as TINYTEXT.
I need to multiply the price by 100, but i i cast that value, no value is coming.
I tried both the below option.
SELECT CAST(Column1 as UNSIGNED) * 100
SELECT CAST(Column1 as SIGNED) * 100
TINYTEXT Sample Data
$19.99
$11.99
its a Dolloar Sign ($19.99 and sometimes value is not present in that column.
Regards
Vikram.
Well, you will have to process the string in there to sanitize the data. Based on the fact that $19.99 is the only variation then it seems safe just to replace the dollar sign:
SELECT REPLACE(price, '$', '') * 100 FROM t
However, you should seriously consider turning that column into DECIMAL. That way you won't face a bug when someone adds an euro or pound sign.

select where in(Float, .....)

I am trying to select some values from mysql with the next sentence:
SELECT
id, lead_id, form_id, field_number, value
FROM
wp_rg_lead_detail
WHERE
field_number IN (6.3, 6.6, 11, 12, 17, 14)
ORDER BY
lead_id, field_number
the field field_number is a float and the select is listing just the 11, 12, 17 and 14 fields but not values from the 6.3 and 6.6
What is wrong with the sentence?
Thanks.
The reason is that 6.3 and 6.6 are not actually stored in your table. Computers cannot perfectly represent most fractional values. When the value stored is compared to 6.3 or 6.6, it does not match, even though it looks like it should. The difference might be at the 9th or 10th decimal place, which you won't normally see.
http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
If you need to exactly compare the values, make them integers or decimals. If nothing will ever have more than 1 number to the right of the decimal point, you can multiply all values by 10 to only work with integers, for example.
There is nothing wrong with the query. The problem is that float is not precise type. Use decimal instead (or change the query to something like ... WHERE (field_number BETWEEN 6.2999 AND 6.3001) OR (field_number BETWEEN 6.5999 AND 6.6001 OR ()... )