I have different data values (types), like 10.00 or 2.00. How can I get only its integer value, so I want to get 10 instead of 10.00 and 2 instead of 2.00?
You can use the FLOOR or TRUNCATE function depending on your intention:
SELECT FLOOR(1.999) -- 1
SELECT FLOOR(-1.999) -- -2
SELECT TRUNCATE(1.999, 0) -- 1
SELECT TRUNCATE(-1.999, 0) -- -1
For example, you cound try to do this:
WHERE CONVERT(your_column, SIGNED INTEGER) AS num
FROM
table
ORDER BY
num;
Based on MySQL Documentation CONVERT() and CAST():
CONVERT() provides a way to convert data between different character sets. The syntax is:
CONVERT(expr USING transcoding_name)
In MySQL, transcoding names are the same as the corresponding character set names.
Besides for you also could work ROUND(X), ROUND(X,D):
Rounds the argument X to D decimal places. The rounding algorithm depends on the data type of X. D defaults to 0 if not specified. D can be negative to cause D digits left of the decimal point of the value X to become zero.
mysql> SELECT ROUND(150.000,2), ROUND(150,2);
+------------------+--------------+
| ROUND(150.000,2) | ROUND(150,2) |
+------------------+--------------+
| 150.00 | 150 |
+------------------+--------------+
Related
I have an int column that contains values no larger than about 20. I want to select as its corresponding upper case letter of the alphabet:
1 = A
2 = B
3 = C
...
I don't care what happens after Z because the column doesn't contain larger values. Is there a simple way to do this with a SQL query, to convert to a single-byte character like this?
Add 64 to your integer and you have the ASCII value of the letter you want.
mysql> select CHAR(1+64);
+------------+
| CHAR(1+64) |
+------------+
| A |
+------------+
Read https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_char
Another alternative specific to MySQL using elt
select elt(col,'A','B','C','D','E','F',...);
Demo
I need to find avg of rating from database with rounded values.I wrote query with avg() is return value correct(4.50000).then i need the rounded value without precision like 5(because avg is 4.50).so i wrote query with round() like as below
SELECT ROUND(AVG(rating)) as avgrate FROM `cust_review` WHERE find_in_set(1,'8,1,22')
its return the value 4.but the correct answer is 5.I was attached my screenshots below
before round up the values
Then my datatype is double(2,1) for rating field
here i edited with table structure
It was worked fine by changing the datatype from double(2,1) to decimal(2,1).
This is documented in Rounding Behavior:
The ROUND() function rounds differently depending on whether its
argument is exact or approximate:
For exact-value numbers, ROUND() uses the “round half up” rule: A value with a fractional part of .5 or greater is rounded up to the
next integer if positive or down to the next integer if negative. (In
other words, it is rounded away from zero.) A value with a fractional
part less than .5 is rounded down to the next integer if positive or
up to the next integer if negative. (In other words, it is rounded
toward zero.)
For approximate-value numbers, the result depends on the C library. On many systems, this means that ROUND() uses the “round to nearest
even” rule: A value with a fractional part exactly half way between
two integers is rounded to the nearest even integer.
The relevant part is: "round to nearest even" - which is 4 for 4.5.
Consider the following example:
create table test(
dcm decimal(2,1),
dbl double
);
insert into test(dcm,dbl)values
(4.5,4.5),
(5.5,5.5);
select dcm, round(dcm), round(dbl) from test;
Result:
| dcm | round(dcm) | round(dbl) |
| --- | ---------- | ---------- |
| 4.5 | 5 | 4 |
| 5.5 | 6 | 6 |
View on DB Fiddle
As you can see - the DECIMAL value is always rounded up, while the DOUBLE value is rounded to the nearest even number.
If you want ROUND() to always round up DOUBLE values, you can first cast them to DECIMAL. Example:
select dbl, round(cast(dbl as decimal(20,10))) from test;
returns
| dbl | round(cast(dbl as decimal(20,10))) |
| --- | ---------------------------------- |
| 4.5 | 5 |
| 5.5 | 6 |
View on DB Fiddle
Or you just cast to the corresponding decimal type, which in your case would be something like
select cast(dbl as decimal(20,0)) from test;
Of course, you can also just store the values in DECICIMAL.
I am looking to find out if there is a way to count the number of trailing zeros in a column. The column is made up of a maximum of 13 numbers as shown below and I want to count all the zeros before an actual number but not sure how to go about doing this.
Example numbers
2200040000000 -- this would have the value 7
1411258181000 -- this would have the value 3
I have managed to do this in Excel but I am trying to do this directly in MySQL in a query rather than importing the data in Excel and then writing the query as theres more steps to go through.
The following is the formula:
=6+RIGHT(TEXT(B17,"0.##############E+00"),2)-LEN(TEXT(B17,"0.##############E+00"))
I would really appreciate it, if somebody could advise on how I could resolve this issue as would really help me to move forward and not go back and forth with Excel.
You could use string function TRIM(), which is available since the early days of MySQL:
char_length(num) - char_length(trim(trailing '0' from num))
trim(...) removes trailing 0s from the string; the difference of lengh between the original value and the trimed value gives you the number of trailing 0s in the string.
Demo on DB Fiddle:
create table t (num bigint);
insert into t values (2200040000000), (1411258181000);
select
num,
char_length(num) - char_length(trim(trailing '0' from num)) cnt_trailing_0s
from t;
num | cnt_trailing_0s
------------: | --------------:
2200040000000 | 7
1411258181000 | 3
You can do it with reverse() like this:
select col,
length(col) - length(reverse(col) + 0) trailing_zeros
from tablename
replace col with the actual name of the column.
If there is a case of the column to contain only zeros then use this:
length(col) - length(reverse(col) + 0) + (col = 0)
See the demo.
Results:
| col | trailing_zeros |
| ------------- | -------------- |
| 2200040000000 | 7 |
| 1411258181000 | 3 |
I have a field for comments used to store the title of the item sold on the site as well as the bid number (bid_id). Unfortunately, the bid_id is not stored on its own in that table.
I want to query items that have a number (the bid_id) greater than 4,000 for example.
So, what I have is:
select * from mysql_table_name where comment like '< 4000'
I know this won't work, but I need something similar that works.
Thanks a lot!
Just get your bid_id column cleaned up. Then index is.
create table `prior`
( id int auto_increment primary key,
comments text not null
);
insert `prior` (comments) values ('asdfasdf adfas d d 93827363'),('mouse cat 12345678');
alter table `prior` add column bid_id int; -- add a nullable int column
select * from `prior`; -- bid_id is null atm btw
update `prior` set bid_id=right(comments,8); -- this will auto-cast to an int
select * from `prior`;
+----+-----------------------------+----------+
| id | comments | bid_id |
+----+-----------------------------+----------+
| 1 | asdfasdf adfas d d 93827363 | 93827363 |
| 2 | mouse cat 12345678 | 12345678 |
+----+-----------------------------+----------+
Create the index:
CREATE INDEX `idxBidId` ON `prior` (bid_id); -- or unique index
select * from mysql_table_name where substring(comment,start,length, signed integer) < 4000
This will work, but I suggest create new column and put the bid value in it then compare.
To update value in new column you can use
update table set newcol = substring(comment,start,length)
Hope this will help
There is nothing ready that works like that.
You could write a custom function or loadable UDF, but it would be a significant work, with significant impact on the database. Then you could run WHERE GET_BID_ID(comment) < 4000.
What you can do more easily is devise some way of extracting the bid_id using available string functions.
For example if the bid_id is always in the last ten characters, you can extract those, and replace all characters that are not digits with nil. What is left is the bid_id, and that you can compare.
Of course you need a complex expression with LENGTH(), SUBSTRING(), and REPLACE(). If the bid_id is between easily recognizable delimiters, then perhaps SUBSTRING_INDEX() is more your friend.
But better still... add an INTEGER column, initialize it to null, then store there the extracted bid_id. Or zero if you're positive there's no bid_id. Having data stored in mixed contexts is evil (and a known SQL antipattern to boot). Once you have the column available, you can select every few seconds a small number of items with new_bid_id still NULL and subject those to extraction, thereby gradually amending the database without overloading the system.
In practice
This is the same approach one would use with more complicated cases. We start by checking what we have (this is a test table)
SELECT commento FROM arti LIMIT 3;
+-----------------------------------------+
| commento |
+-----------------------------------------+
| This is the first comment 100 200 42500 |
| Another 7 Q 32768 |
| And yet another 200 15 55332 |
+-----------------------------------------+
So we need the last characters:
SELECT SUBSTRING(commento, LENGTH(commento)-5) FROM arti LIMIT 3;
+-----------------------------------------+
| SUBSTRING(commento, LENGTH(commento)-5) |
+-----------------------------------------+
| 42500 |
| 32768 |
| 55332 |
+-----------------------------------------+
This looks good but it is not; there's an extra space left before the ID. So 5 doesn't work, SUBSTRING is 1-based. No matter; we just use 4.
...and we're done.
mysql> SELECT commento FROM arti WHERE SUBSTRING(commento, LENGTH(commento)-4) < 40000;
+-------------------+
| commento |
+-------------------+
| Another 7 Q 32768 |
+-------------------+
mysql> SELECT commento FROM arti WHERE SUBSTRING(commento, LENGTH(commento)-4) BETWEEN 35000 AND 55000;
+-----------------------------------------+
| commento |
+-----------------------------------------+
| This is the first comment 100 200 42500 |
+-----------------------------------------+
The problem is if you have a number not of the same length (e.g. 300 and 131072). Then you need to take a slice large enough for the larger number, and if the number is short, you will get maybe "1 5 300" in your slice. That's where SUBSTRING_INDEX comes to the rescue: by capturing seven characters, from " 131072" to "1 5 300", the ID will always be in the last space separated token of the slice.
IN THIS LAST CASE, when numbers are not of the same length, you will find a problem. The extracted IDs are not numbers at all - to MySQL, they are strings. Which means that they are compared in lexicographic, not numerical, order; and "17534" is considered smaller than "202", just like "Alice" comes before "Bob". To overcome this you need to cast the string as unsigned integer, which further slows down the operations.
WHERE CAST( SUBSTRING(...) AS UNSIGNED) < 4000
searched around awhile for a solution to this problem, but no answer yet.
Have a column of alphanumeric model ID numbers to populate an index in a certain order. Two different attempts with the order they produced:
ORDER BY Model_ID ASC
1278-8
211E
350-50
996
3800P
AP23
AP263
AP26M
JA042
ORDER BY CAST(Model_ID AS UNSIGNED), Model_ID
AP23
AP263
AP26M
JA042
211E
350-50
996
1278-8
3800P
However, I need to have it sorted like so, with all of the integer-starting numbers exhausted first:
211E
350-50
996
1278-8
3800P
AP23
AP263
AP26M
JA042
Help? Thanks
For the sample data, this will get the desired order:
ORDER BY Model_ID+0=0, Model_ID+0, Model_ID ASC
Let's unpack that a bit.
The expression Model_ID+0 evaluates Model_ID in a numeric context, by adding zero to it. Basically, MySQL gets whatever leading characters that can be converted to a number, and disregards the rest. For values that can't be interpreted as a number, MySQL returns 0.
The first expression checks if the numeric value is zero, so those will be sorted last. (MySQL returns numeric value of 1 for boolean TRUE, 0 for FALSE.)
The second expression gets the non-zero values sorted in numeric order.
NOTE: these expressions "work" for the sample data; the edge case is values that have leading zeros as the numeric value, e.g. '000ABC' will be sorted after all the other "numeric" values. And MySQL doesn't stop at just the integer portion, if there's a dot character, that can be interpreted as a decimal point.
You can see the values of the expressions (for testing), by including them in the SELECT list, e.g.
SELECT Model_ID+0=0, Model_ID+0, ...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table (model_id VARCHAR(20) NOT NULL PRIMARY KEY);
INSERT INTO my_table VALUES
('1278-8'),
('211E'),
('350-50'),
('996'),
('3800P'),
('AP23'),
('AP263'),
('AP26M'),
('JA042');
SELECT model_id FROM my_table ORDER BY model_id + 0 = 0,model_id + 0;
+----------+
| model_id |
+----------+
| 211E |
| 350-50 |
| 996 |
| 1278-8 |
| 3800P |
| AP23 |
| AP263 |
| AP26M |
| JA042 |
+----------+