MySQL - how to round - mysql

I have this in one of my queries:
FORMAT(ROUND(AVG(`rating` * 2)) / 2, 1) AS `average_rating`
If rating has a value of, say, 1.45 - then I get 1.5, which is what I want. When it rounds to whole numbers, I get 1.0, 2.0, etc. I don't want that. When I get whole numbers, I'd like to drop the decimal value.
Is there a way to do this in MySQL?

Try in this way :
(TRIM(TRAILING '.' FROM(CAST(TRIM(TRAILING '0' FROM
FORMAT(ROUND(AVG(`rating` * 2)
) / 2, 1))AS char)))) AS `average_rating`

Related

sql - Add 0 after a numeric value

I have columns in my sql table. I am wondering how can I add zero after numeric values in my columns. So for example:
I have values e.g 9, 2, 7, 10. I want to add a zero after these numbers. I want them to be 90, 20, 70, 100.
There are some values in the columns that already have 0s after them e.g 70, 20, 100. These ones should retain their values.
How do I go about this?
Just multiple the column by ten (not sure what your table name is, edit that query):
UPDATE __TABLE__
SET mt_ca1 = (mt_ca1 * 10),
mt_ca2 = (mt_ca2 * 10)
WHERE mt_ca1 < 100 OR mt_ca2 < 100;
It is not clear if you want to add zeroes after only double-digit numbers or all numbers. MySQL has substring functionality though you'd need to clarify your needs.
You can use CONCAT and CASE
assuming the column type is INT
use CASE to check if the value multiplied to 10 is less than or equal to 100.
SELECT
(CASE
WHEN (mt_ca1*10) <= 100
THEN CONVERT(CONCAT(mt_ca1,'0'),UNSIGNED INTEGER)
ELSE mt_ca1
END) AS mt_ca1
FROM yourtable

Rounding mysql 0.5 doesn't always go up

https://i.stack.imgur.com/pxEQW.png
CREATE TABLE `zz` (
`jum_r` double DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `zz` VALUES (71045),(31875),(12045),(172125),(27325),(5465);
SELECT
jum_r,
ROUND(ROUND((jum_r * 1.1), 2), 2) as q_gross,
ROUND(jum_r * 1.1) as gross,
ROUND((jum_r * 10 / 100), 2) as q_ppn,
ROUND(jum_r * 10 / 100) as ppn
FROM zz;
I have data according to the picture. Why does rounding 0.5 not always go up ...? What's wrong with my query? Thanks
For exact-precision numbers (e.g. DECIMAL) MySQL rounds 0.5 up to the next highest integer. For imprecise numbers (e.g. FLOAT) MySQL counts on the underlying C library's rounding, which is often "round-to-even". Doc ref here
After clarifying below, this should be your answer:
CASE would help. Basically:
WHEN (ROUND(jum_r * 1.1) < 0.5) THEN FLOOR(ROUND(jum_r * 1.1)), WHEN (ROUND(jum_r * 1.1) >= 0.5 THEN CEILING(ROUND(jum_r * 1.1)). Not pretty but should work

Mysql extract part of a string (substr, slice ?)

I want to substr of slice because I have a database that contains application name and their versions.
I'd like to get every version that needs to be followed. (every last version of each branch).
Those version name could be formatted 8.XX.YY.ZZZZ. And I'd like to get every last version for the 3 first set of number.
For exemple :
800000018
800000024
800010000
800010009
800020001
800020005
801000004
801000005
800020006
800020007
800010010
800020009
I would only get :
801000005 (8.1.0.5)
800020009 (8.0.2.9)
800010010 (8.0.1.10)
800000024 (8.0.0.24)
I've been thinking of a procedure that would do something like this :
get max version (here it'd be 8.1.0.5).
Then, get max version but substract by 1 if XX > 1 (8(XX -1))
And again, get max version and substract by 1 if YY>1 (800(YY-1))
Continue until there is only the 4 last number left and the first number that aren't 0.
In SQL it'd look like that :
select max(version_name) from application;
while (XX >0) SET XX=XX-1;
select max(version_name) from application where version_name LIKE '8XX';
while (YY>0) SET YY=YY-1;
select max(version_name) from application where version_name LIKE '800YY';
End there and last version_name should be = 80000ZZZZ.
Is there a way to substr if possible from the end of the string.
I have a filter in JS that transform it on the format that I want (VV.XX.YY.ZZZZ) if it can help :
parseInt(version.slice(0, -8)), parseInt(version.substr(-8, 2)),
parseInt(version.substr(-6, 2)), parseInt(version.slice(-4))
I hope it is possible.
you can group by substring and get the max
select max(version_name)
from application
group by
substring(version_name,1,1),
substring(version_name,2,2),
substring(version_name,4,2)
and order/parse it as you wish
My query in MYSQL
SELECT
CONCAT_WS(
'.',
SUBSTRING(VERSION, -9, 1),
SUBSTRING(VERSION, -8, 2) +0,
SUBSTRING(VERSION, -6, 2) +0,
SUBSTRING(VERSION, -4, 4) +0
) AS result,
VERSION
FROM
`test`
Output:
result version
--------------------
8.0.0.18 800000018
8.0.2.9 800020009
8.0.1.10 800010010
8.1.0.5 801000005

How can I structure a MySQL query that references select results in calculations?

I have a number of blockhash based fingerprints of images stored in a table along with the web site member who uploaded it and the local URL of the image:
member varchar(8)
fingerprint char(64)
url varchar(80)
I am trying to do a Hamming Distance calculation on these hashes to determine how likely they are to be a match (reference mysql hamming distance between two phash).
Given the easiest way I have seen to do this is to use MySql's bit_count function to XOR the two and produce a total number of on bits, I know that I have to break the 64-character hash into 4 chunks, then convert each to unsigned integer before feeding it to bit_count. So, I have a query that does such (run from Linux command line, hence the argument variables):
select bit_count(cast(conv(substr('$1', 1, 16), 16, 10) as unsigned) ^ cast(conv(substr($2, 1, 16), 16, 10) as unsigned)) +
bit_count(cast(conv(substr('$1', 17, 16), 16, 10) as unsigned) ^ cast(conv(substr('$2', 17, 16), 16, 10) as unsigned)) +
bit_count(cast(conv(substr('$1', 33, 16), 16, 10) as unsigned) ^ cast(conv(substr('$2', 33, 16), 16, 10) as unsigned)) +
bit_count(cast(conv(substr('$1', 49, 16), 16, 10) as unsigned) ^ cast(conv(substr('$2', 49, 16), 16, 10) as unsigned));
..And this produces the proper results between two fingerprints.
However, I need a query that will find matching fingerprints from anyone other than the member in question. Basically:
select member, url
from images
where (Hamming Distance between <fingerprint> and (select hashes from member) < 10)
AND member != "<value>"
I think I might want to create a stored procedure to determine the Hamming Distance, then maybe limit the results I have to check from the entire database to something like those matching the first 10 characters. But is there a better way?
A hamming_distance stored function is a good idea. Then you can use it in a join.
SELECT i1.member, i1.url
FROM images AS i1
JOIN images AS i2 ON i1.member != i2.member AND hamming_distance(i1.fingerprint, i2.fingerprint) < 10
WHERE i2.member = #member_in_question
The function was the trick. It chunks the fingerprint and returns the distance between the two. Then it was a simple matter of a select:
select member, url, fingerprint, hamming_dist(fingerprint, '$fingerprint') as distance from images where hash REGEXP '$find' && hamming_dist(hash, '$hash') < 8 && member != '$member';"
The REGEXP just limited the search down to probable matches, it consisted of the first and last character in the fingerprint. Doing that dropped the query time down from .35 seconds to .12 seconds.
Thanks for the help!

MySQL Rounding functions

I am looking for a ROUND() type function that would allow me to round numbers to 1 decimal place but also to the nearest 0.5.
To illustrate:
19.425 => 19.5
19.124 => 19.0
Similarly:
12.654 => 12.5
12.845 => 13.0
As vissi said, to get the result you want you'll need 2 round statements. (To get to 1 decimal place)
SELECT ROUND(ROUND(19.425 * 2) / 2, 1) #19.5
SELECT ROUND(ROUND(19.124 * 2) / 2, 1) #19.0
SELECT ROUND(ROUND(12.654 * 2) / 2, 1) #12.5
SELECT ROUND(ROUND(12.845 * 2) / 2, 1) #13.0
You can multiply your number by two, round and then divide by two. Note, that the result may still be not very accurate (sth like 19.5000000000001).