MySQL different counts between "where =" and "where like" - mysql

1. select count(*) from tableX where code = "XYZ";
2. select count(*) from tableX where code like "%XYZ";
Result for query 1 is 18734. <== Not Correct
Result for query 2 is 93003. <== Correct
We know that query 2's count is correct based on independent verification.
We expect these two queries to have the exact same count for each because we know that no rows in tableX have a code that ends with "XYZ", so the wildcard at the beginning shouldn't affect the query.
Why would these queries produce different counts?
We have already researched the differences between "=" comparison and "like" string comparison, but based on all our verification checks, we still don't understand why this would give us different counts
We have confirmed the following:
There are no leading or trailing characters in the "code" field
There are no hidden characters (tried all found here: How can I find non-ASCII characters in MySQL?)
The collation is "utf8_unicode_ci"
We are using MySQL version 5.5.40-0ubuntu0.12.04.1.

Try this in order to get your answer:
SELECT code
FROM tableX
WHERE code LIKE "%XYZ"
AND code <> "XYZ"
LIMIT 10
My guess is that some of your codes end with a lowercase xyz, and since LIKE is case-insensitive, it matched these where = did not.

where code = "XYZ"; gives exact match whereas where code LIKE "%XYZ"; includes partial match as well. In your case, there could be an extra space present which is giving wrong count. Consider trimming before comparing like
where UPPER(TRIM(code)) = 'XYZ';

We restarted the server that the database resides on, we re-ran the queries, and now they all are producing the expected, correct results...
We'll have to look into possibilities for why this "fixed" the issue.

Related

What is the purpose of using WHERE COLUMN like '%[_][01][7812]' in SQL statements?

What is the purpose of using WHERE COLUMN like '%[_][01][7812]' in SQL statements?
I get some result, but don't know how to use properly.
I see that it is searching through the base, but I don't understand the pattern.
Like selects strings similar to a pattern. The pattern you're looking at uses several wildcards, which you can review here: https://www.w3schools.com/SQL/sql_wildcards.asp
Briefly, the query seems to ba matching any row where COLUMN ends in an _ then a 0 or a 1, then a 7,8,1, or 2. (So it would match 'blah_07' but not 'blah_81', 'blah_0172', or 'blah18')
First thing as you might be aware that where clause is used for filtering rows.
In your case (Where column Like %[_][01][7812]) Means find the column ending with [_][01][7812] and there could be anything place of %
declare
#searchString varchar(50) = '[_][01][7812]',
#testString varchar(50) = 'BeginningOfString' + '[_][01][7812]' + 'EndofString'
select CHARINDEX(#searchString, #testString), #testString, LEN(#testString) as [totalLength]
set #testString = '[_][01][7812]' + 'EndofString'
select CHARINDEX(#searchString, #testString), #testString, LEN(#testString) as [totalLength]
set #testString = 'BeginningOfString' + '[_][01][7812]'
select CHARINDEX(#searchString, #testString), #testString, LEN(#testString) as [totalLength]
Although you've tagged your post MySQL, that code seems unlikely to have been written for it. That LIKE pattern, to me, resembles Microsoft SQL Server's variation on the syntax, where it would match anything ending with an underscore followed by a zero or a one, followed by a 7, an 8 a 1 or a 2.
So your example 'TA01_55_77' would not match, but 'TA01_55_18' would, as would 'GZ01_55_07'
(In SQL Server, enclosing a wildcard character like '_' in square brackets escapes it, turning it into a literal underscore.)
Of course, there may be other RDBMSes with similar syntax, but what you've presented doesn't seem like it would work on the data you've got if running in MySQL.

MySQL query LIKE %...% query returning other results?

So I'm trying to code a PHP script, but we'll just leave it at the SQL part of things since this is where the issue is arising. I've a SELECT * query which should only grab from the rows where the user ID matches, and the badge ID meets their userID followed by an underscore. Although, it's grabbing results that shouldn't be included?
Here's my SQL query:
SELECT *
FROM `user_badges`
WHERE `user_id` = 1
AND `badge_id` LIKE '%1_%'
That should only return badges that start/contain 1_, it is grabbing all the badges that do contain/start with 1_ but it's also grabbing it215. If I search a different user ID, for example my own, it will grab all the badges with 3_ AND it's also grabbing ACH_RoomDecoFurniCount31 which is confusing because it doesn't contain 3_. Maybe there's more to it? Could someone please point me in the right direction.
You need to escape the _ as it's a wildcard character. Your query would should be like this:
SELECT *
FROM `user_badges`
WHERE `user_id` = 1
AND `badge_id` LIKE '%1\_%'
_ is also a wildcard in SQL - A substitute for a single character
_ is also a wildcard character. It means "any single character" (whereas % is "any sequence of characters").
You could escape/quote that _ or use the LOCATE function instead of a pattern match.
WHERE badge_id LIKE '%1\_%'
WHERE locate('1_', badge_id) > 0
_ is a wildcard "_ matches exactly one character." so what you are saying is:
% : starts with anything(or nothing)
1: contains 1
_: has exactly 1 of % (or anything, or nothing)
http://dev.mysql.com/doc/refman/5.7/en/string-comparison-functions.html

MySQL REGEXP - Where the column contains the regular expression

So I have a table called "lu_regex" with a column called "regex"
Select * from lu_regex;
athedsl-\d+
i5[93][0-9a-fA-F]+\.versa
5ac[a-f0-9]+.+sky
The table contains 1000's of rows, with various Regular Expressions syntax, i'm just showing three in this example.
Now I'm trying to take user input and match that input against the rows in the table. So I'm doing this.
SELECT * FROM lu_regex where '5aca3a11.bb.sky.comr' regexp regex;
regex
5ac[a-f0-9]+.+sky
1 row returned.
I'm getting back what I expected, with that query, then I try this one.
SELECT * FROM lu_regex where 'athedsl-07371.home.otenet.gr' regexp regex;
0 rows returned.
It should match on "athedsl-\d+", but i'm assuming it has something to do with the "\d". I even tried adding this to the database "athedsl-\\d+" and that didn't cause a match either.
I'm trying to stick to a MySQL solution, what am I doing wrong, this should be possible.
I just found this link, it looks like a bug that hasn't been fixed. It was verified in 2013.
https://bugs.mysql.com/bug.php?id=70413
Bug #70413 \d is not working in REGEXP for a MySQL query
I think the solution is going to be is to replace all \d with [0-9]

Why does MySQL equal sign matches wrong entries?

I'm running a select query on two tables and searching the matching entries with an equal sign. In my understanding, MySQL should only return entries exactly matching the WHERE condition, however it's returns entries like when I use the LIKE statement:
Any explanations why would the first row be returned as a result of the query?
EDIT:
Here's the query:
SELECT `ts`.`ticker_symbol`, `sm`.`id` AS `matchescount`, `sm`.`ticker_symbol_ids`
FROM `mk_ticker_symbols` `ts`, `mk_submissions` `sm`
WHERE `sm`.`ticker_symbol_ids` = `ts`.`id` AND `ts`.`id` = "1506"
EDIT 2:
Here's the SQL Fiddle:
http://sqlfiddle.com/#!9/5550b/1/0
EDIT 3:
Here's the SQL Fiddle with JOINs:
http://sqlfiddle.com/#!9/5550b/2/0
Piero,
The one with JOINs can be corrected. CAST() within JOIN will fix the issue.
INNER JOIN `mk_submissions` `sm`
ON `sm`.`ticker_symbol_ids` = CAST(`ts`.`id` AS CHAR(10))
I know you are not looking for solution, but I still post it.
The problem is VERY interesting.
I searched online, and did some trial-error on my DB. I have no explanations....
I tried to put 1506, in the second, or third place in comma separated list - the query works fine.
So, I have a feeling, that in case of JOIN with comma-separated list, comma gets treated as wildcard 'end of string'...
If you ever find an explanation, please post it here.
When evaluating expressions, MySQL converts both arguments (in this case) to floating point numbers to compare them. This is because one is a string, and one is an integer, which results in the final condition in the link above being applied.
In all other cases, the arguments are compared as floating-point
(real) numbers.
So what is the floating point equivalent of the string "1506,..."?
Running the following on my test server:
SELECT "1506,3101,26673,26745,2277,1216,26847,26865,20711,1468,26947,233,20539,26985"+0.0
Results in:
1506
Which of course equals the floating point version of the integer 1506.
So, everything is behaving as expected. At least, assuming you expect this floating point comparison to be happening.
I can't give a full explanation for the problem, but I have a solution.
ts.id is likely and INTEGER so your where clause should be
`ts`.`id` = 1506
(remove quotes from the number).
Also you should use a join instead of a where clause to match the tables:
FROM `mk_ticker_symbols` `ts`
JOIN `mk_submissions` `sm` on sm.ticker_symbol_ids = ts.id
I found the answer to this issue. I was comparing string to integer here:
`sm`.`ticker_symbol_ids` = `ts`.`id` AND `ts`.`id` = "1506"
The problem is that, this is converted to integer internally for comparison:
1506,3101,26673,26745,2277,1216,26847,26865,20711,1468,26947,233,20539,26985
Because of the comma, MySQL thinks it's a decimal or float with the floating point, and everything after the comma is omitted for comparison. So it becomes 1506 instead of 1506,3101,26673,26745,2277,1216,26847,26865,20711,1468,26947,233,20539,26985, and that matches the WHERE condition.
#cyadvert and #Willem_Renzema were absolutely correct.
To resolve the issue
I only needed to:
CAST(`ts`.`id` AS CHAR)

What's the difference between '=' operator and LIKE when not using wildcards

I do this question, because I can't found a question with the same reason. The reason is when I use LIKE, I get CONSISTENT RESULTS, and when I use (=) operator I get INCONSISTENT RESULTS.
THE CASE
I have a BIG VIEW (viewX) with multiple inner joins and left joins, where some columns have null values, because the database definition allows for that.
When I open this VIEW I see for example: 8 rows as result.
When I run for example: select * from viewX where column_int = 34 and type_string = 'xyz', this query shows me 100 rows, that aren't defined in the result of the view. [INCONSISTENT]
BUT
When I run select * from viewX where column_int = 34 and type_string like 'xyz', this query show me only 4 rows, that is defined in the view when I opened (see 1.) [CONSISTENT]
Does anyone idea, of what is happening here?
From the documentation.....
'Per the SQL standard, LIKE performs matching on a per-character basis, thus it can produce results different from the = comparison operator: '
more importantly (when using LIKE):
'string comparisons are not case sensitive unless one of the operands is a binary string'
from :
http://dev.mysql.com/doc/refman/5.0/en/string-comparison-functions.html
Per the MySQL documentation LIKE does function differently than =, especially when you have trailing or leading spaces.
You need to post your actual query but I'm guessing it's related to the known variances.