Select from a range of categories [duplicate] - mysql

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.

Related

Match exact pattern [duplicate]

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.

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 to concatinate string with multiple complex SELECT statements and place it in a column [duplicate]

This question already has answers here:
Can I concatenate multiple MySQL rows into one field?
(16 answers)
Closed 2 years ago.
I have a scenario where I'd like to get columns with information stored in a very specific way.
I'd like to select n number of columns from a table A, concatinate their values, and then add m number of more values which should be grabbed from other tables by joining one of their columns to the current statement's column.
Cars - (car_id, model_id, plate_id, brand_name, year_of_release, custom_column)
Model - (model_id, model_name, description)
Plates - (plate_id, car_owner_name, registration_state)
Let's say we have these tables and what we want to do is place the following information in one column:
'car_id, brand_name, year_of_release, plate_id, model_name, car_owner_name, registration_state'
for each row of the Cars table as a 'custom_column' value
I'd like it to be a comma-separated string. Is there a way to do this with MySQL?
You seem to want concat_ws():
select concat_ws(', ', car_id, brand_name, year_of_release, plate_id, model_name, car_owner_name, registration_state)
from t;

MYSQL QUERY with multiple options from a single table [duplicate]

This question already has answers here:
SQL query to count number of times certain values occur in multiple rows
(5 answers)
Closed 4 years ago.
SELECT firstname, lastname, id
FROM contact
WHERE id IN
(SELECT contactid
FROM taglist
WHERE contactid IN
(SELECT contactid
FROM customerlist
WHERE companyid = 1) AND (tagid = 1 OR tagid = 4))
I have the query above where there is a single table that has a userid and a tag id. Each user can have multiple tags that are listed as separate entries on this table.
I need to be able to select only users with two or more specified tags. I thought the above query would do this, but it is returning every user with either tag 1 or tag 4.
If I change it to this: (tagid = 1 AND tagid = 4)) I get 0 results because it is only looking at each individual entry, and no entry has more than one tag per user.
This example only has two tags selected, but the goal here is to allow the end user to be able to select any number of available tags and only show results where the user matches all selected tags.
I don't have any way to know a specific number of tags that are going to be selected to match on. Currently there are 20 available tags, and clients can add their own tags if they wish.
So how do I accomplish this? I am very new to SQL queries, and not very familiar with joins yet so I am thinking this is going to have something to do with it, but I don't know. Any nudges in the right direction would be greatly appreciated.
You can get contacts with the two tags by doing:
SELECT contactid
FROM taglist
WHERE tagid IN (1, 4)
GROUP BY contactid
HAVING COUNT(*) = 2;
The rest of your query is doing other stuff not mentioned in your question, so it is unclear what you really want. Obviously, you can use this as a subquery to get full contact information.

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?