Confusing mysql select results with LIKE and multiple zeros (%00%) - mysql

I have created a search query to search a table for a string in multple fields. It works for every string except if the string contains only one or multiple zeros eg: %000% returns rows with 2 or less zeros.
The search fields:
`par_partno` varchar(20) utf8_general_ci
`par_group_id` varchar(16) utf8_bin
`par_desc` text utf8_general_ci
`par_details` text utf8_general_ci
I already tried to cast par_partno to char CAST(par_partno AS CHAR) but the result is the same.
The query:
select `par_id`, `pag_id`, `par_partno`, `par_group_id`,`par_cond`, `par_desc`,`par_price`,
`par_stock`, `par_feature`, `par_weight`, `par_details`, `par_related`, `par_meta`,
`par_picture`, `par_lastmod`
from `parts`
where concat(`par_partno`, `par_group_id`, `par_desc`, `par_details`) like "%000%"
order by `par_group_id` asc
Wrong results:
[
{"par_id":"145100","pag_id":"1","par_partno":"7101263500","par_group_id":"01-00-12","par_cond":"New","par_desc":"Pedal Assy W\/ Booster Mbc, Clutch Cylinder","par_price":"1450.00","par_stock":"1","par_feature":"0","par_weight":"0.1","par_details":"","par_related":null,"par_meta":null,"par_picture":"0","par_lastmod":"2019-01-04 18:14:12"},
{"par_id":"145106","pag_id":"2","par_partno":"7121051100","par_group_id":"01-01-102","par_cond":"New","par_desc":"Seal Intake Valve","par_price":"5.95","par_stock":"1","par_feature":"0","par_weight":"0.1","par_details":"","par_related":"[\"7121040061\"]","par_meta":null,"par_picture":"0","par_lastmod":"2019-01-04 18:14:12"},
{"par_id":"145169","pag_id":"2","par_partno":"7122015100","par_group_id":"01-01-91","par_cond":"New","par_desc":"Engine Gasket Set","par_price":"199.00","par_stock":"1","par_feature":"0","par_weight":"6.4","par_details":"","par_related":null,"par_meta":null,"par_picture":"0","par_lastmod":"2019-01-04 18:14:12"}
]

I might be missunderstanding your question, but isn't the checked string a concatenation of e.g.
par_partno":"7101263500","par_group_id":"01-00-12"
so
710126350001-00-12
which contains a "000" substring.

An improvement to Robin's reference answer:
(too big / codey for comments)
Run only one LIKE query, by combining the searched columns into one CONCATenation.
HAVING CONCAT_WS('-',par_partno,par_group_id,par_descpar_details) LIKE "%000%"
This function combines all checked columns into one string and seperates them with a - (any value that is not part of the LIKE).
This also removes the LOWER() function as it's needless when working with digits.

The hints helped me to resolve this problem.
I removed the concat and replaced it with:
WHERE LOWER(par_partno) LIKE "%000%" OR LOWER(par_group_id) LIKE "%000%"
OR LOWER(par_desc) LIKE "%000%" OR LOWER(par_details) LIKE "%000%"

Related

SQL - match last two characters in a string

I have a small mysql database with a column which has format of a field as following:
x_1_1,
x_1_2,
x_1_2,
x_2_1,
x_2_12,
x_3_1,
x_3_2,
x_3_11,
I want to extra the data where it matches last '_1'. So if I run a query on above sample dataset, it would return
x_1_1,
x_2_1,
x_3_1,
This should not return x_2_12 or x_3_11.
I tried like '%_1' but it returns x_2_12 and x_3_11 as well.
Thank you!
A simple method is the right() function:
select t.*
from t
where right(field, 2) = '_1';
You can use like but you need to escape the _:
where field like '%$_1' escape '$'
Or use regular expressions:
where field regexp '_1$'
The underscore character has special significance in a LIKE clause. It acts as a wildcard and represent one single character. So you would have to escape it with a backslash:
LIKE '%\_1'
RIGHT does the job too, but it requires that you provide the proper length for the string being sought and is thus less flexible.
Duh, I found the answer.
Use RIGHT (col_name, 2) = '_1'
Thank you!

Mysql 'match against' with multiple criteria

How to compare records from one column with 'match against'? That code is not working properly:
$sql = 'SELECT * FROM `database` WHERE MATCH (`content` WHERE `id` != \'\')AGAINST (`content` WHERE `id` = \'\' IN BOOLEAN MODE)';
$p = $db->query($sql);
As documented, the MATCH() syntax is like this:
MATCH (col1,col2,...) AGAINST (expr [search_modifier])
And is described as:
MATCH() takes a comma-separated list that names the columns to be searched. AGAINST takes a string to search for, and an optional modifier that indicates what type of search to perform. The search string must be a string value that is constant during query evaluation. This rules out, for example, a table column because that can differ for each row.
So, the syntax you have used is completely invalid.
I'm not sure of what you're asking for. Someone else has provided a pretty good response to a similar question posted in the following link:
Mysql search for string and number using MATCH() AGAINST()
Again it seems to me that you are trying to match patterns/expressions between 2 columns from 2 different tables, if I have understood your example correctly. If so, then maybe the solution provided in the link isn't 'the way to go'. It's up to you, hope it helps..

How to query MySQL for fields containing null characters

I have a MySQL table with a text column. Some rows have null characters (0x00) as part of this text column (along with other characters).
I am looking for a query that will return all rows containing any null characters for this column, but I cannot figure out how the proper syntax for my "where column like '%...%'" clause.
Thank you!
Right after I submitted the question, a suggested link to this related question provided my answer:
Query MySQL with unicode char code
WHERE column LIKE CONCAT("%", CHAR(0x00 using utf8), "%");
The following worked for me...
WHERE column LIKE "%\0%";

Can I achieve Natural Sorting on a VARCHAR field which contains various length alphanumeric values?

I'm trying to write a MySQL query which will allow me to achieve natural sorting on a VARCHAR product code field containing various string lengths and formatted values.
I have tried many of the techniques found searching Stack Overflow but I can't get any to work for my scenario:
product_code (Sample Data)
BA112
BA113
BA27
BA12
112
998
BA113[1]
BA113[2]
Should sort to:
112
998
BA12
BA27
BA112
BA113
BA113[1]
BA113[2]
Any thoughts?
The way you have described the results, the following will work:
order by length(product_code), product_code;
If you specifically want the numbers to appear first and they can be longer, then:
order by (product_code like REGEXP '^[0-9]*') desc
length(product_code),
product_code
The only answer I can find now is ordering by string length first and alphanumerically then:
ORDER BY CHAR_LENGTH(product_code), product_code
But I think that your BA27 is really like "BA" and "27" and you want to order it by alphabetic first and numerid then, isn't it?
If so, you should store the alphabetic and the numeric part in different fields.
Remember to use CHAR_LENGTH() MySQL function, specially if you are using UTF encoding, because of the multi-byte characters (like "Ñ" or "¿").
Try this:
select product_code
from sample_data
order by (concat(space(10-length(product_code)),product_code)) asc
The important part being the order by (concat...
Makes all values 10 characters long with spaces padded to the left.

MySQL query - select postcode matches

I need to make a selection based on the first 2 characters of a field, so for example
SELECT * from table WHERE postcode LIKE 'rh%'
But this would select any record that contains those 2 characters at any point in the "postcode" field right? I am in need of a query that just selects the first 2 characters. Any pointerS?
Thanks
Your query is correct. It searches for postcodes starting with "rh".
In contrast, if you wanted to search for postcodes containing the string "rh" anywhere in the field, you would write:
SELECT * from table WHERE postcode LIKE '%rh%'
Edit:
To answer your comment, you can use either or both % and _ for relatively simple searches. As you have noticed already, % matches any number of characters whereas _ matches a single character.
So, in order to match postcodes starting with "RHx " (where x is any character) your query would be:
SELECT * from table WHERE postcode LIKE 'RH_ %'
(mind the space after _). For more complex search patterns, you need to read about regular expressions.
Further reading:
http://dev.mysql.com/doc/refman/5.1/en/pattern-matching.html
http://dev.mysql.com/doc/refman/5.1/en/regexp.html
LIKE '%rh%' will return all rows with 'rh' anywhere
LIKE 'rh%' will return all rows with 'rh' at the beginning
LIKE '%rh' will return all rows with 'rh' at the end.
If you want to get only first two characters 'rh', use MySQL SUBSTR() function
http://dev.mysql.com/doc/refman/5.1/en/string-functions.html#function_substr
Dave, your way seems correct to me (and works on my test data). Using a leading % as well will match anywhere in the string which obviously isn't desirable when dealing with postcodes.