SELECT on a varchar field that has text and numbers - mysql

I have a field remote_number, which is Varchar(30).
Most data is a number ranging from 3 to 11 digits long.
When a call is anonymous, this fields value is set to 'anonymous'.
I need to filter data from this field where the value is either >999 OR anonymous.
I can do these queries independently, for example,
SELECT * FROM call_history WHERE remote_number>999;
or
SELECT * FROM call_history WHERE remote_number='anonymous';
When combining the 2, such as
select * from call_history where (remote_number>999 OR remote_number='anonymous');
All data that had anonymous in the remote_number field is truncated due to not being a double.
Warning | 1292 | Truncated incorrect DOUBLE value: 'anonymous'
How can I adjust this query so that the 'anonymous' data is not truncated?
Edit:data type1
query ran
Warning

The reason this does not work, is if we say remote_number>999 we are implying that remote_number is a number but it's clear the returned value is a string not a number.
To fix I specified char length.
AND (char_length(remote_number)>3 OR remote_number='anonymous'

Related

MySQL ERROR 1264 (22003): Out of range value for column

I get this error:
ERROR 1264 (22003): Out of range value for column 'median_comments' at
row 1
after running this query:
update influencers set `median_comments` = 1347 WHERE `id` = 1;
I'm not sure why this fails on this number which doesn't have any decimals and which is only 4 digits.
The field type is:
median_comments decimal(10,8)
You are using DECIMAL(10,8) that means max digits before decimal would be (10 - 8) = 2.
Reference: DECIMAL Data Type Characteristics
The declaration syntax for a DECIMAL column is DECIMAL(M,D). The ranges of values for the arguments are as follows:
M is the maximum number of digits (the precision). It has a range of 1 to 65.
D is the number of digits to the right of the decimal point (the scale). It has a range of 0 to 30 and must be no larger than M.
To fix the error, change your datatype to DECIMAL(10,2).
ALTER TABLE `influencers`
CHANGE COLUMN `median_comments` `median_comments` DECIMAL(10,2) NOT NULL DEFAULT 0;
If you are using decimal(10,8) as data type it means you are specifying 8 digits after decimal place which leaves only (10 - 8 i.e 2 digits) for your whole number.
In this case since your number 1347 contains 4 digits (whole number) hence you are getting the error as "Out of range value" since you are allowed only 2.
You should consider changing it to at least decimal (12,8) which will leave you 4 digits for your whole number part and your above command should work.
Please refer to post - Number format issue in Oracle. Same issue.
As you like me came here from google and your issue is related to Doctrine, and your column type is type="decimal", then you should configure precision and scale properties of your column in the right way.
For me, it was like before:
/** #ORM\Column(name="revenue", type="decimal", scale=4, nullable=true) */
private $revenue;
after
/** #ORM\Column(name="revenue", type="decimal", precision=14, scale=4, nullable=true) */
private $revenue;
It will be converted to DECIMAL(14,4), which means fourteen digits total, four of which are to the right of the decimal point.
Don't forget to prepare migration and run it to apply the changes.
Finally, you should get SQL like this:
ALTER TABLE project_finance CHANGE revenue revenue NUMERIC(14, 4) DEFAULT NULL

MySQL strange behavior when comparing comma-separated string with number

I am experiencing some weird behavior with MySQL. Basically I have a table like this:
ID string
1 14
2 10,14,25
Why does this query pull id 2?
SELECT * FROM exampletable where string = 10
Surely it should be looking for an exact match, because this only pulls id 1:
SELECT * FROM exampletable where string = 14
I am aware of FIND_IN_SET, I just find it odd that the first query even pulls anything. Its behaving like this query:
SELECT * FROM exampletable where string LIKE '10%'
When you compare a numeric and a string value, MySQL will attempt to convert the string to number and match. Number like strings are also parsed. This we have:
SELECT '10,14,25' = 1 -- 0
SELECT '10,14,25' = 10 -- 1
SELECT 'FOOBAR' = 1 -- 0
SELECT 'FOOBAR' = 0 -- 1
SELECT '123.456' = 123 -- 0
SELECT '123.456FOOBAR' = 123.456 -- 1
The behavior is documented here (in your example it is the last rule):
...
If one of the arguments is a decimal value, comparison depends on the
other argument. The arguments are compared as decimal values if the
other argument is a decimal or integer value, or as floating-point
values if the other argument is a floating-point value.
In all other cases, the arguments are compared as floating-point
(real) numbers.

select int column and compare it with Json array column

this is row in option column in table oc_cart
20,228,27,229
why no result found when value is 228 but result found when value is 20 like below :
select 1 from dual
where 228 in (select option as option from oc_cart)
and result found when I change value to 20 like
select 1 from dual
where 20 in (select option as option from oc_cart)
The option column data type is TEXT
In SQL, these two expressions are different:
WHERE 228 in ('20,228,27,229')
WHERE 228 in ('20','228','27','229')
The first example compares the integer 228 to a single string value, whose leading numeric characters can be converted to the integer 20. That's what happens. 228 is compared to 20, and fails.
The second example compares the integer 228 to a list of four values, each can be converted to different integers, and 228 matches the second integer 228.
Your subquery is returning a single string, not a list of values. If your oc_cart.option holds a single string, you can't use the IN( ) predicate in the way you're doing.
A workaround is this:
WHERE FIND_IN_SET(228, (SELECT option FROM oc_cart WHERE...))
But this is awkward. You really should not be storing strings of comma-separated numbers if you want to search for an individual number in the string. See my answer to Is storing a delimited list in a database column really that bad?

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