MySQL CHAR_LENGTH returns wrong number - mysql

I'm making a serial system for my site, and it using the MySQL CHAR_LENGTH function to get all the serials with the matched length. Thing is, it's returning strings that are more than I'm looking for. I've also tried with CHARACTER_LENGTH and LENGTH, having no impact on the result :/.
This is my I/O:
SELECT serials.code
FROM serials
WHERE CHARACTER_LENGTH(code) = 12
These are the results:
niels-er-sej
KUVX-21-40
KUVX-21-40
As you can see, the last two, are only 10 characters, yet they show up when I search for 12?
I've added a picture of the Character lengths as request:

Related

MySQL throwing error "Error Code: 3685. Illegal argument to a regular expression" when calculating accurate occurrence of phrase(s) inside column

As I mentioned in the Q-title, as now the MySQL has been heavily upgraded to version 8, which expectedly provides much new features including shortened characters for Word Boundary matching, calculating exact occurrence of phrase(s) inside column where one row-column(cell) may contain multiple occurrences of searched term/phrase must become easier to achieve.
Yet when I am using this proper looking query to count the exact occurrence of string it throws the below given error:
SELECT
ROUND((LENGTH(`column_name`) - LENGTH(REGEXP_REPLACE(`column_name`,
"^[[:<:]]Home Depot[[:>:]]$",
''))) / LENGTH('Home Depot')) AS `found`
FROM
<DB>.<TableName>;
Where if there are 2 rows as below:
Home Depot is a good one but Home Depot
Home Depot is a bad one
Then it must return found(count of total occurrence) as 3 instead of just no. of rows 2.
But on the contrary it throws error: Error Code: 3685. Illegal argument to a regular expression.
And if I use \\b instead of the [[:<:]], then it gives too many rows of the order of 1000000 which is ofcourse the wrong count as there aren't that much rows in the entire table, so it's just the Regex engine messing up.
Anyone care to help out achieve what I want ?
You need to change the word boundaries to \\b. And to match Home Depot anywhere in the string, you must remove the ^ and $ anchors. Finally, to get the total number of replacements, you have to use SUM() to add up the values from each row.
I don't think you need to use ROUND() since the numerator should always be an exact multiple of the denominator.
Putting it all together:
SELECT SUM((LENGTH(`column_name`) -
LENGTH(REGEXP_REPLACE(`column_name`, "\\bHome Depot\\b", '')))
/ LENGTH('Home Depot')) AS found
FROM db.tablename

MySQL LIKE Operator with Special Characters Confusion

First let me apologize I have not been successful in finding anything online with this specific scenario.
I have been using MySQL for quite some time, but I am hoping to get some clarification on a certain situation I have come across, which honestly bothers me quite a bit.
I'm trying to match a string in a MySQL column that contains both \ and % literal characters using the LIKE operator.
Inside the table I have two records:
id value
-----------------------
1 100\\%A
2 100\%A
They both contain literal special characters.
If I do a SELECT, in an attempt to only match the first record (id=1), I would expect to write the query as such:
SELECT * FROM table_name WHERE value LIKE '%0\\\\\%A'
(\\\\ to match two literal backslashes, plus a backslash before % to match a literal %)
However, It only matches the row (id=2), which makes no sense to me.
If I change the query a little to be:
SELECT * FROM table_name WHERE value LIKE '%0\\\\%A'
I would expect to match the id=1 row only, (\\\\ to match 2 literal backslashes, and the % is not literal and should represent a wildcard). But instead, it matches both rows?
row (id=2) only has a single backslash but still matches.
Is row id=2 matching because the first 2 backslashes are matching the \, the 3rd backslash is ignored for some reason, and the 4th backslash is allowing a literal match on the %?
If I do a:
SELECT * FROM table_name WHERE value LIKE '%0\\\\\\\%A'
I for some reason get row (id=1), when I would expect to get no matches whatsoever.
I'm trying to find a solution in which I can do partial matches on any series of characters accurately, including those with consecutive special characters such as the scenario above. However, I'm having an impossible time trying to plan for situations such as these.
Any input would be greatly appreciated.
Maybe this help you understand the usage of escape chars in mySQL
https://stackoverflow.com/a/27061961/634698

MySQL, equal or not equal?

I am a bit puzzled to see this on MySQL
SELECT 1='1x';
gives me 1
Whereas
SELECT 1='2x';
gives me 0 (as expected)
When doing a binary compare
SELECT CAST(1 AS BINARY)=CAST('1x' AS BINARY);
it gives me 0 (also as expected)
Question: How can I stop MySQL from behaving like this? I want '=' to act as 100% binary equal. I don't want MySQL to assume or guess what I might wanted to compare.
When comparing strings and numbers then MySQL automatically makes a conversion.
So the string gets converted to a number and it starts from left to right and tries to make a number from it.
So
'1x' => 1
'x1' => 0 //because it does not start with a number on the left
You can't change that behaviour. And you should not compare different data types anyway. So it is your fault :)

Trouble displaying ColdFusion Results in proper order when Field length varies 101 vs 1000

I'm using MySQL. I have a table with a field called UnitName. I just want to display all the UnitNames in order. The Unit Names can vary:
101
T-101
G-202
1005
O-1305
When I display them using ORDER BY UnitName, The results are not sorted properly. For instance 1000 will come before 101, T-2000 will come before T-201. If they were all numeric values, I would try to use CAST(UnitName AS INT), but unfortunately I have to deal with the Alpha (and other '-') characters.
I believe the way to approach this is to make sure that the UnitNames have the same length, and then they will sort properly. So basically I am trying to insert a number of zeros into the middle of the string until the lengths are identical and then ORDER BY that.
My query currently is listed below.
<cfquery name="Get"datasource="rent">
SELECT * FROM Units
ORDER BY Left(UnitName,2)+#RepeatString(0, 10-'LEN(UnitName)')#+right(UnitName, 'LEN(UnitName)'-2)
</CFQUERY>
I'm basically saying sort by "the 2 left characters of the string+(a number of 0s determined by the number 10 minus the length of the string)+the characters on the right side of the string (except the first 2).
When I just do a CFOUTPUT of this the UnitName comes out perfectly. I do have to had some # to make it work: #Left(UnitName,2)##RepeatString(0, 10-'#LEN(UnitName)#')##right(UnitName, len(UnitName)-2)#
But the query fails to execute as written below. I've narrowed it down to the middle section where I'm trying to determine the number of Zeros to insert. Specifically if I use:
#RepeatString(0, 10-5)#, the query will execute. But the minute I put 'LEN(UnitName)' instead of 5, the query fails. Any idea what I'm doing wrong?
Any insight is appreciated--I've been banging my head against a wall.

MySQL Regexp won't work

I have the following query:
SELECT `admin_users`.*
FROM `admin_users`
WHERE (avatar REGEXP 'avatars/Name-[0-9]+.jpg+')
ORDER BY `admin_users`.`avatar`
DESC LIMIT 1
It's ok if I have something like:
avatars/Name-5.jpg
avatars/Name-6.jpg
But if I have, avatars/Name-15.jpg, for example, it doesn't return in query.
In other words, It only works for 1 digit, not for more. How can I solve it?
When comparing strings (an that is what avatar is), "avatars/Name-1..." comes before "avatars/Name-5..." simply because the string "1" comes before "5".
It is not practical to order those by an embedded number. This would do what you want, but it is pretty cryptic:
ORDER BY 0 + MID(avatar, 14)
To explain
MID will start at the 14th character of 'avatars/Name-15.jpg' and extract '15.jpg'.
0+ will take that string, convert it to a number and deliver the number 15. (When a string is turned into a number, the first characters are taken as long as it looks like a number. So, 0+'abc' will deliver 0, since there is nothing at the beginning of abc that looks like a number.)
If the left part were not exactly 14 characters in all cases, the trick will fail. And it may get so complicated as to be 'impossible' in SQL.