Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Mysql select distinct user with each of their own preference, please help me with this simple example

Let’s say I have a user and preference table, as well as a bridge table user_preference between the two:

/* user table:  */
+----------+--------------+
| Field    | Type         |
+----------+--------------+
| id       | int          |
| username | varchar(255) |
+----------+--------------+

/*  preference table: */
+------------+--------------+
| Field      | Type         |
+------------+--------------+
| preference | varchar(255) |
+------------+--------------+

/* user_preference table:  */
+-----------------+--------------+
| Field           | Type         |
+-----------------+--------------+
| user_id         | int          |
| preference_name | varchar(255) |
+-----------------+--------------+

For instance there are 3 preferences to choose from: "swimming", "watching TV", "cycling". And one user can have zero or all 3 of the preferences, which is reflected on the user_preference table.

Now I want to query 10 different users, and with all of them each of their own preferences, how to construct a select statement for that?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

So far I have tried something like this:

SELECT u.*, p.preference_name 
FROM user u 
LEFT JOIN user_preference p ON p.user_id = u.id
LIMIT 10;

/* Result:  */
id | username | preference_name

1  | user1    | swimming
1  | user1    | cycling
2  | user2    | null
3  | user3    | watching TV
... /* rest of the result  */

As you can see the result will return a duplicate user1, and it won’t be 10 distinct users. I’m aware of the distinct and group by keywords, it doesn’t solve the problem, as it will only return a single preference for a user, while the user can have multiple preferences.

Is it possible to do that with one single select statement? Any comment or help is greatly appreciated!

>Solution :

Try this.

SELECT u.*, 
       GROUP_CONCAT(DISTINCT p.preference_name) AS prefs
  FROM user u 
  LEFT JOIN user_preference p ON p.user_id = u.id
 GROUP BY u.id
LIMIT 10;

The GROUP_CONCAT() will make a comma-separated list of preferences for each user.

Pro tip. When tables get very large, altering ENUMs to add more values gets very time-consuming. Plus, it’s usually unwise to design a database so it needs lots of ALTER TABLE statements as it grows. So, the approach you have outlined is the right way to go if you want your possible preferences to be open-ended.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading