96

My query is:

SELECT * FROM table WHERE id IN (1,2,3,4);

I use it for usergroups and a user can be in more than one group. but it seems that when a record has multiple id like 1 and 3, mySQL does not return that row.

Is there any way to get that row too?

Qix - MONICA WAS MISTREATED
  • 14,451
  • 16
  • 82
  • 145
netcase
  • 1,319
  • 2
  • 13
  • 15
  • 7
    Please post an example of the rows that do not properly return from this query. Assuming you aren't storing the `id` as a comma-separated list or something, multiple rows _will_ return from your query. – Michael Berkowski Mar 16 '12 at 11:20
  • 1
    well it is a comma seperated list, for example => 3,4 will not returned by mySQL. I see the problem, it's about the comma but how could I do it? – netcase Mar 16 '12 at 11:23
  • 1
    @user762683, Please use a proper profile name? and what is the data type of this `id`, varchar or set or enum? – Starx Mar 16 '12 at 11:25
  • possible duplicate of [How to search for a comma separated value](http://stackoverflow.com/questions/3852443/how-to-search-for-a-comma-separated-value) – Michael Berkowski Mar 16 '12 at 11:26
  • 4
    @Starx What business of yours is the profile name someone uses? – Michael Berkowski Mar 16 '12 at 11:27
  • Here you got your username! and the data type is "tinytext" – netcase Mar 16 '12 at 11:28
  • Also http://stackoverflow.com/questions/1987829/searching-from-comma-separated-value – Michael Berkowski Mar 16 '12 at 11:28
  • 1
    @Michael, See How easy and correct is sounds to correspond to the OP as `netcase` instead of `@user762683`? – Starx Mar 16 '12 at 11:30
  • @Starx you can press Tab to auto-complete a username while typing comments... – Michael Berkowski Mar 16 '12 at 11:38
  • When asking questions like this it is helpful for you to show how you are defining the fields you are asking about. In your case here, how are you storing the user groups a user is in? – D Mac Mar 16 '12 at 11:57

3 Answers3

94

Your query translates to

SELECT * FROM table WHERE id='1' or id='2' or id='3' or id='4';

It will only return the results that match it.


One way of solving it avoiding the complexity would be, chaning the datatype to SET. Then you could use, FIND_IN_SET

SELECT * FROM table WHERE FIND_IN_SET('1', id);
Starx
  • 77,474
  • 47
  • 185
  • 261
  • Cannot reproduce any error. The requested query works for me. I get ALL records from 'table' with the listed ids. – B.F. Jan 11 '15 at 15:03
  • Cannot recommend using a bitfield. It's an anti-pattern (Multi-Valued Attribute, like CSV columns but binary.) It's tough to sort, search, or update. – txyoji May 08 '23 at 16:44
43

You have wrong database design and you should take a time to read something about database normalization (wikipedia / stackoverflow).

I assume your table looks somewhat like this

TABLE

group_id user_ids name
1 1,4,6 group1
2 4,5,1 group2

so in your table of user groups, each row represents one group and in user_ids column you have set of user ids assigned to that group.

Normalized version of this table would look like this

GROUP

id name
1 group1
2 group2

GROUP_USER_ASSIGNMENT

group_id user_id
1 1
1 4
1 6
2 4

Then you can easily select all users with assigned group, or all users in group, or all groups of user, or whatever you can think of. Also, your sql query will work:

/* Your query to select assignments */
SELECT * FROM `group_user_assignment` WHERE user_id IN (1,2,3,4);

/* Select only some users */
SELECT * FROM `group_user_assignment` t1
JOIN `group` t2 ON t2.id = t1.group_id
WHERE user_id IN (1,4);

/* Select all groups of user */
SELECT * FROM `group_user_assignment` t1
JOIN `group` t2 ON t2.id = t1.group_id
WHERE t1.`user_id` = 1;

/* Select all users of group */
SELECT * FROM `group_user_assignment` t1
JOIN `group` t2 ON t2.id = t1.group_id
WHERE t1.`group_id` = 1;

/* Count number of groups user is in */
SELECT COUNT(*) AS `groups_count` FROM `group_user_assignment` WHERE `user_id` = 1;

/* Count number of users in group */
SELECT COUNT(*) AS `users_count` FROM `group_user_assignment` WHERE `group_id` = 1;

This way it will be also easier to update database, when you would like to add new assignment, you just simply insert new row in group_user_assignment, when you want to remove assignment you just delete row in group_user_assignment.

In your database design, to update assignments, you would have to get your assignment set from database, process it and update and then write back to database.

Here is sqlFiddle to play with.

w.Daya
  • 443
  • 1
  • 7
  • 12
Buksy
  • 11,571
  • 9
  • 62
  • 69
5

you must have record in table or array record in database.

example:

SELECT * FROM tabel_record
WHERE table_record.fieldName IN (SELECT fieldName FROM table_reference);
Jared Forth
  • 1,577
  • 6
  • 17
  • 32
misbah dino
  • 59
  • 1
  • 1
  • A subselect isn't required. `IN (1,2,3,4)` is perfectly valid. Also, I don't understand how this explains "when a record has multiple id like 1 and 3, mySQL does not return that row" in the Question. – Scratte Jul 29 '20 at 12:15