Store only numbers after Comma mysql - mysql

How to save only the numbers after the comma with mysql functions?
eg : 16.03 ----> 03

If I understand correctly, you want the fractional part of the number. In MySQL, you can do this with mod():
select mod(14.03, 1)
Yields "0.03".
EDIT:
Juhana makes a very good point. MySQL freely converts between numbers and strings, so you can use substr() on this:
select substr(14.03, locate('.', 14.03)+1)
If you want the digits after a comma, replace '.' with ','.

If your values come from a table, you will have to be prepared to deal with the fact that some value could be integers (i.e.: having no decimal separator while converted to a string):
SELECT IF(LOCATE('.', value), SUBSTRING_INDEX(value,'.', -1), "0") FROM tbl;
See http://sqlfiddle.com/#!2/062c8/11

Or simply:
14.03 % 1
--> 0.03
Also works for negative numbers:
-14.03 % 1
--> -0.03
If you are after exactly the two digits after the decimal point (and you are dealing with positive numbers only) you can do the following:
substring(format( num %1,2),3,2) -- num being the column (integer of float, double ...)
--> 03 -- for num=14.03
--> 00 -- for num=14
--> 05 -- for num=14.046739
Of course, if you want all digits, you could leave out the format()
substring(num %1,3,2)
--> 03 -- for num=14.03
--> -- for num=14
--> 046739 -- for num=14.046739
but that makes the integer case quite ugly.

Related

MySQL REGEXP does not work properly with Russian chars

SELECT 'Hello' REGEXP '^[^aeiouAEIOU][A-Za-z]*$' -> 1
SELECT 'Привет' REGEXP '^[^аеиоуыэюяАЕИОУЫЭЮЯ][А-Яа-я]*$' -> 0 - it must return 1.
MySQL's REGEXP only works with bytes. Russian characters are each 2 bytes.
For limiting to Cyrillic, this seems to be correct:
SELECT HEX('Привет') REGEXP '^((D0|D1)..)+$'; -- > 1
(I'll get to the issue of avoiding leading vowels in a minute.)
To explain:
All Russian characters are 2 bytes, the first byte being hex D0 or D1. (There may be non-Russian characters starting that way; I'm ignoring that problem.)
(...|...) - | means 'OR'.
.. matches a 2-byte hex, saying that the second byte can be anything (this is overkill but may not hurt).
(...)+ - The plus means one or more occurrence.
The ^ and $ 'anchor' the regexp to encompass the entire string.
Back to the no-leading-vowel issue. Now we need to play some painful games to list the vowels; their HEX seem to be
D0, followed by any of B0 B5 B8 BE
90 95 98 9E, or
D1, followed by any of 83 8B 8D 8E 8F
A3 AB AD AE AF
Example: select hex('э'); --> D18D.
Putting it all together will be messy because MySQL does not have the (? tools to say "not". So, I will start by testing for a leading vowel:
SELECT HEX('Привет')
REGEXP '^(D0(B0|B5|B8|BE|90|95|98|9E))|(D1(83|8B|8D|8E|8F|A3|AB|AD|AE|AF))'
correctly fails.
Now to put things together:
SELECT NOT HEX('Привет')
REGEXP '^(D0(B0|B5|B8|BE|90|95|98|9E))|(D1(83|8B|8D|8E|8F|A3|AB|AD|AE|AF))'
AND HEX('Привет')
REGEXP '^((D0|D1)..)+$';
The first part check for NOT a leading vowel; the second part check for all characters being Russian.
That test case works, and 'э' came back with 0, but I may have goofed somewhere.
(That was a challenge.)

I need a trigger to create id's in my sql database with a string and some zeros

I'm currently using this trigger which adds id's with 3 zeros and two zeros and then the id from the sequences table.
BEGIN
INSERT INTO sequences VALUES (NULL);
SET NEW.deelnemernr = CONCAT('ztmr16', LPAD(LAST_INSERT_ID(), 3, '0'));
END
I changed the 3 to 4 but then it didn't increment the id anymore, resulting in and multiple id error. It stayed at ztmr16000. So what can I do to add more zeros and still get the id from the sequencestable?
The MySQL LPAD function limits the number of characters returned to the specified length.
The specification is a bit unclear, what you are trying to achieve.
If I need a fixed length string with leading zeros, my approach would be to prepend a boatload of zeros to my value, and then take the rightmost string, effectively lopping off extra zeros from the front.
To format a non-negative integer value val into a string that is ten characters in length, with the leading characters as zeros, I'd do something like this:
RIGHT(CONCAT('000000000',val),10)
As a demonstration:
SELECT RIGHT(CONCAT('000000000','123456789'),10) --> 0123456789
SELECT RIGHT(CONCAT('000000000','12345'),10) --> 0000012345
Also, I'd be cognizant of the maximum length allowed in the column I was populating, and be sure that the length of the value I was generating didn't exceed that, to avoid data truncation.
If the value being returned isn't be truncated when it's inserted into the column, then what I think the behavior you observe is due to the value returned from LAST_INSERT_ID() exceeding 1000.
Note that for a non-negative integer value val, the expression
LPAD(val,3,'0')
will allow at most 1000 distinct values. LPAD (as I noted earlier) restricts the length of the returned string. In this example, to three characters. As a demonstration of the behavior:
SELECT LPAD( 21,3,'0') --> 021
SELECT LPAD( 321,3,'0') --> 321
SELECT LPAD( 54321,3,'0') --> 543
SELECT LPAD( 54387,3,'0') --> 543
There's nothing illegal with doing that. But you're going to be in trouble if you depend on that to generate "unique" values.
FOLLOWUP
As stated, the specification ...
"adds id's with 3 zeros and two zeros and then the id from the sequences table."
is very unclear. What is it exactly that you want to achieve? Consider providing some examples. It doesn't seem like there's an issue concatenating something to those first five fixed characters. The issue seems to be with getting the id value "formatted" to your specification
This is just a guess of what you are trying to achieve:
id value formatted return
-------- ----------------
1 0001
9 0009
22 0022
99 0099
333 0333
4444 4444
55555 55555
666666 666666
You could achieve that with something like this:
BEGIN
DECLARE v_id BIGINT;
INSERT INTO sequences VALUES (NULL);
SELECT LAST_INSERT_ID() INTO v_id;
IF ( v_id <= 9999 ) THEN
SET NEW.deelnemernr = CONCAT('ztmr16',LPAD(v_id,4,'0'));
ELSE
SET NEW.deelnemernr = CONCAT('ztmr16',v_id);
END IF;
END

MySQL: compare a mixed field containing letters and numbers

I have a field in the mysql database that contains data like the following:
Q16
Q32
L16
Q4
L32
L64
Q64
Q8
L1
L4
Q1
And so forth. What I'm trying to do is pull out, let's say, all the values that start with Q which is easy:
field_name LIKE 'Q%'
But then I want to filter let's say all the values that have a number higher than 32. As a result I'm supposed to get only 'Q64', however, I also get Q4, Q8 and so for as I'm comparing them as strings so only 3 and the respective digit are compared and the numbers are in general taken as single digits, not as integers.
As this makes perfect sense, I'm struggling to find a solution on how to perform this operation without pulling all the data out of the database, stripping out the Qs and parsing it all to integers.
I did play around with the CAST operator, however, it only works if the value is stored as string AND it contains only digits. The parsing fails if there's another character in there..
Extract the number from the string and cast it to a number with *1 or cast
select * from your_table
where substring(field_name, 1, 1) = 'Q'
and substring(field_name, 2) * 1 > 32

substring dynamic number of characters

I'm working with 2 sets of data that were merged together, but they're inconsistent in their format. Some are 10 characters, all numbers. Others may have a separator : at position 4. I need to substring the first 4 characters. But if the 4th character is a : substring only the first 3 characters.
Does mysql have an IF functionality to determine the number of characters to substring based on the character in position 4?
select substring(id, 1 , 3/4) from table1
You can treat the field like it's colon separated and do this to select only the first part:
SELECT SUBSTRING_INDEX(id, ':', 1)
See also: SUBSTRING_INDEX()

Single quotes affecting the calculations in Select query

SELECT COUNT(*) FROM area
WHERE ROUND(SQRT(POWER(('71' - coords_x), 2) +
POWER(('97' - coords_y), 2))) <= 17
==> 51
SELECT COUNT(*) FROM area
WHERE ROUND(SQRT(POWER((71 - coords_x), 2) +
POWER((97 - coords_y), 2))) <= 17
==> 22
coords_x and coords_y are both TINYINT fields containing values in the range [1, 150]. Usually MySQL doesn't care if numbers are quoted or not.. but apparently it does in this case.
The question is just: Why?
MySQL always cares about data types. What happens is that your code relies in automatic type casting and performs math on strings (which can hold a number or not). This can lead to all sort of unpredictable results:
SELECT POW('Hello', 'World') -- This returns 1
To sum up: you need to learn and use the different data types MySQL offers. Otherwise, your application will never do reliable calculations.
Update:
One more hint:
TINYINT[(M)] [UNSIGNED] [ZEROFILL]
A very small integer. The signed range
is -128 to 127. The unsigned range is
0 to 255.
URL:
http://dev.mysql.com/doc/refman/5.1/en/numeric-type-overview.html
I hope you are not trying to store 150 in a signed tinyint column.