Match exact pattern [duplicate] - mysql

This question already has answers here:
Is storing a delimited list in a database column really that bad?
(10 answers)
Closed 1 year ago.
I have a MySQL table that contains books information. Part of that information is a special character (^) separated list of values that corresponds to the book names. I'm having some problems getting the correct information out of the database. Table looks like
id OwnedBooks CustomerID
1 Harry^Two States^Tintin 101
2 Harry Potter^Tintin 290
3 Harry Prizoner of Azhaban 278
So when I search for 'Harry' in the ownedbooks column, I should get only one record i.e. (record id=1)
My query looks like below
SELECT * FROM books where ownedbooks like '%Harry%'
This query return all the records as I have used like, but I wanted to match the exact string with (^) as a separation.
When I search for 'Harry Potter' it should return the second record i.e (record id=2)

If you want to match a book named exactly "Harry" then you may use the following LIKE logic:
SELECT *
FROM books
WHERE ownedbooks LIKE '%^Harry^%' OR -- appears in the middle of the list
ownedbooks LIKE 'Harry^%' OR -- appears in the beginning of the list
ownedbooks LIKE '^Harry'; -- appears in the end of the list
You would be making a good design decision to move away from storing ^ delimited data in your table. Instead, get each book title onto a separate record.

Related

MYSQL query assistance with wildcards [duplicate]

This question already has answers here:
Query with multiple values in a column
(4 answers)
Closed 2 years ago.
first, here is how the mysql data looks like:
"group" column in "table_a"
---------------
user1 = 123,456,789
user2 = 789,897,12
user3 = 789
user4 = 4789,123,456
---------------
I am trying to return all users who have "789" in their group column field.
I have:
SELECT * from table_a WHERE group LIKE %789%
this query returns user1,user2,user3,user4 (user4 should not be part of the results)
and:
SELECT * from table_a WHERE group LIKE %789%
only returns user3
How can I return only user1, user2 and user3?
Obviously your query is missing single quotes around the right operand of like:
where grp like '%789%'
However please note that this is not a reliable to check if a value belongs to a comma-separated list, since it would partially match on any value. If your list is like '123,45,67890', then the like expression would match, while you probably don't want that.
I would recommend find_in_set():
where find_in_set('789', grp)
Finally: you should not have a data model where multiple numbers are stored in a single string columns. Instead, you should have another table, where each value is stored on a separate row. More about this can be read in this famous SO question.
Note: group is a language keyword, hence not a good choice for a column name; I renamed it to grp in the above code snippets;

How can I select using an intersection of comma-separated value?

I have a column holds a comma-separated values.
1,2,3
4,6,7
2,3,8
12234,5467,232445,232455,11223
With given criteria of array (e.g., 1,4,9),
How can I select rows whose value contains any of given?
I mean when I am given with 1,4,9, I need to select
1,2,3 -- has 1
4,6,7 -- has 4
UPDATE
I have a table who has a column of comma-separated values of other entity's primary keys.
I understand the reason why the original table designer did this. The other entity actually resides in other database which means not joinable. Or he or she just wanted to do like this.
The STUDENT table
id name classes
---------------------------
1 John 1,2,3
2 Jane 2,8,233423423
The Criteria
With given comma-separated class numbers, find students who is attending any of them.
given: 1 -> select John
given: 233423423 -> select Jane
given: 1,233423423 -> select Both
You can use dynamic template for regular expression. For example:
SET #Criteria='1,4,9';
SELECT `name`
FROM STUDENT
WHERE STUDENT.classes REGEXP concat('(^|,)(', REPLACE(#Criteria, ',', '|'), ')(,|$)');
If you have an input 1,4,9 and you have to find rows where any of 1, 4, or 9 occur in a comma-separated list?
SELECT ...
FROM MyTable
WHERE FIND_IN_SET(1, mycolumn)
OR FIND_IN_SET(4, mycolumn)
OR FIND_IN_SET(9, mycolumn)
See https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_find-in-set for information about this function.
This should illustrate to you that storing comma-separated lists is not a good idea for a relational database, when you want to treat the elements of the list as discrete values.
See also my answer to Is storing a delimited list in a database column really that bad?

\n Separated Search in Column

I have a district table, in which we store user’s preferred districts in district table district_id (varchar(250)) field(column). Value stored in this field is like 1 2 5 6 1 by using \n. So please tell me, how can i search in this specific column?
Don't. Your design is absolutely horrible and this is why you are having this issue in the first place.
When you have a N-N relationship (a user can have many preferred districts and each district can be preferred by many users) you need to make a middle table with foreign keys to both tables.
You need:
A table for districts with only information about districts.
A table with users with only information about users.
A table for preferred districts by user with the district number and the user id as columns and foreign key constraints. This will make sure that any user can have an unlimited number of preferred districts with easy querying.
I would not recommend performing searches on data stored that way, but if you are stuck it can be done with regular expressions.
You have to deal with starting and ending matches for a string as well. So a regular LIKE is not going to work.
MySQL Regular Expressions
Give this SQL a try. To search for the number 5
SELECT * FROM `TABLE` WHERE `field` REGEXP '\\n?(5)\\n?';
If you want to match using the LIKE feature. It can be done using multiple rules.
SELECT * FROM `TABLE` WHERE `field` LIKE '%\\n5\\n%' OR LIKE '5\\n%' OR LIKE '%\\n5';
Note that you have to use a double \ to escape for a new line.
Easiest way is to just use a LIKE query, like this:
SELECT * FROM `preferred_districts` WHERE `district_id` LIKE '%6%';
To make sure it's the right one you'll receive (because this will also match id 16, 26, 674 etc.) you'll have to check manually if it's correct. In php (dunno if you use it) you could use the snippet below:
$id_field = '1 2 5 6 17';
$ids = explode("\n", $id_field);
if(in_array(6, $ids)) {
echo 'Yup, found the right one';
}
Important Although the above will work, your database design isn't how it should be. You should create (what is sometimes called) a pivot table between the districts and the users, something like below.
(Table 'users_preferred_districts')
user_id | district_id
--------+------------
2 | 1
2 | 17
9 | 21
Like this it's quite easy to retrieve the records you want...
I have used mysql function FIND_IN_SET() and I got the desired result through this function.
I got help from this tutorial.
http://www.w3resource.com/mysql/string-functions/mysql-find_in_set-function.php

Select from a range of categories [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Mysql WHERE problem with comma-separated list
I have the next info in a table
name categories
------ -----------
John 1,4
Jim 4,1
JAck 4,1
between other.
I want to select all the rows that pertain to category 4, but this statement..
SELECT name, categories
FROM `mytable`
WHERE 4 IN (categories)
returns only "Jim" and "Jack" but not "John". What am I doing wrong?
Edit: Sadly I cant change the structure of the table. I need to use that comma-list style
I am not sure why you are storing a comma separated list in a single column. But it you cannot change the table structure, you will want to use LIKE to compare the data:
select name, categories
from yourtable
where categories like '%4%'
See SQL Fiddle with Demo
Or you can use the FIND_IN_SET function:
select name, categories
from yourtable
where FIND_IN_SET(4,categories) > 0
See SQL Fiddle with Demo
My suggestion would be to change your table to not store your data in this comma-separated format, it will cause nothing but problems.

In mysql is there a way to query for a string in the db but only do an alphanumeric comparison (ignore special chars)

I'm trying to figure out whether it is possible to query a mysql table for a string but have it ignore special characters in the field that is querying in the db....
A better way of clarifying what I'm trying to achieve could be with an example.
If I had a table named "Games" which had 2 columns being "id" and "title" which contained these rows:
id title
-----------------------
1 f-zero
2 quake
3 quake 4
And I wanted to be able to search for "fzero" (notice the search string is without the hyphen), i.e.
SELECT g.* FROM Games as g WHERE alphanumeric(title) = "fzero";
Would this be possible in one way or another?
Thanks in advance!
If you have some structure in the title attribute values, you can use a regexp condition, like:
SELECT g.* FROM Games as g WHERE title REGEXP 'f[0-9\-!\\]*z[0-9\-!\\]*e[0-9\-!\\]*r[0-9\-!\\]*o[0-9\-!\\]*';