简体   繁体   中英

MySQL to fetch related users

I have two tables Schools and Users

Table School

-----------------------------------------------------
| id |     name    |  city  |     major    | userID |
----------------------------------------------------|
| 1  |  school A   | chicago |    CS       |    1   |
----------------------------------------------------|
| 2  |  school B   | chicago |    CS       |    1   |
----------------------------------------------------|
| 3  |  school A   | chicago |    CS       |    2   |
----------------------------------------------------|
| 4  |  school C   | chicago |    Art      |    2   |
----------------------------------------------------|
| 5  |  school B   | chicago |    CS       |    3   |
----------------------------------------------------|
| 6  |  school D   | chicago |    Math     |    3   |
----------------------------------------------------|
| 7  |  school A   |New York |    CS       |    3   |
----------------------------------------------------|
| 8  |  school B   | chicago |    Art      |    3   |
-----------------------------------------------------

Table Users

--------------------
| id |     name    |
____________________
| 1  |    User A   |
____________________
| 2  |    User B   |
____________________
| 3  |    User C   |
____________________
| 4  |    User D   |
____________________
| 5  |    User E   |
____________________

The userID field in the schools table is a foreign key to the id field in the users table. I want to write a MySQL statement that takes a given userID and lists all classmates of that user.

So, for the example above, a class mate of User A (ID#1) is a user that went to the same school as User A , is located in the same city , and has the same major . Thus, valid classmates for User A are only User B (ID#2) AND User C (ID#3).

Right now, I am using two MySQL statements to accomplish this goal. The first one is this

SELECT id FROM schools WHERE userID = '1'

which lists all schools for User A . Then I use PHP to loop through the results and for each row I run the following

    SELECT userID from schools WHERE 
name city LIKE '%$chicago%' 
AND name LIKE '%$school A%' 
AND major LIKE '%$CS%'

This works fine and returns the right list of userIDs. However, I am wondering if there is a more efficient way to do this in one SQL statement and without having to use PHP.

You can do it like this:

select distinct u.name
from Users u
join School s on s.userID = u.id
join (
            select distinct s.name, s.city
            from School s
            inner join Users u on u.id = s.userID
            where u.name = 'User A'
           ) aux on s.name = aux.name and s.city = aux.city
where u.name <> 'User A'

In the aux query you select the name 's and city 's of a @user and then select all users with those requirements and that aren't the @user itself.

You may replace 'User A' by a variable.

Your SCHOOL table is not considered right. It violates the rules of relational database management systems.

One must make 3 more tables: one for school name, another for city name, and a third for major name. All of these must be different tables with ids.

Clearly name column and city column have a many-to-many relationship so one must make a lookup table for this.

The same applies for major column. It seems like a lot of tables but then your extraction of any value will be simple.

OK, I made some changes to your tables. I prefer this way to store the data:

table student
col.
id 
name
major
reg.no.   (to make each student unique)

table school
col.
id 
name

table city
col.
id 
name

table student_school (lookup table)
col.
student_id
school_id

table school_city
col.
school_id
city_id

Prefer these tables and you will find that every query can be made with ease. If you have any problem with understanding this, let me know.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM