Reputation: 67
My mySQL database has a schools
and a users
table. Each school has an id
that identifies it. When a user joins a school, the user's school
column is set to the id
of that school. I need to execute a request which does the following:
school
column is set to that school's id
.)All I need in return is the user object. I know I could use PHP for some of the work, but I would like to do the majority in the SQL query. If possible, I would like to do this all in one request. Is this possible? So far I've come up with:
SELECT *
FROM `schools`
INNER JOIN `users` ON schools.id = users.school
ORDER BY RAND( )
LIMIT 1
at which point I could save the selected school's id in PHP as $schoolID and execute another request:
SELECT *
FROM `users`
WHERE school =2
AND attempts !=0
ORDER BY (
successes / attempts
) DESC , RAND( )
LIMIT 1
Is there a way to combine them into one SQL query to save server load?
Structure:
Users Table:
+------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | | auto_increment |
| username | char(35) | NO | | | |
| school | int(11) | YES | | | |
| successes | int(11) | NO | | 0 | |
| attempts | int(11) | NO | | 0 | |
+------------+----------+------+-----+---------+----------------+
Schools Table:
+------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | | auto_increment |
| name | char(35) | NO | | | |
+------------+----------+------+-----+---------+----------------+
Sample Data: Users table:
id username school successes attempts
1 josh 1 0 0
2 james 2 0 1
3 ashley 2 2 2
4 john 1 1 1
5 will 3 4 8
6 jack 3 1 2
Schools table:
id name
1 school1
2 school2
3 school3
4 school4
Only schools 1-3 should be able to be chosen from schools
, and only user 4 should show if school 1 was chosen, user 3 should show if school 2 was chosen, and either user 5 or 6 should show if school 3 was chosen.
Upvotes: 0
Views: 1702
Reputation: 5670
Revised again so that it will NOT retrieve all records in the inner query. Safe to use with larger data sets. The inner select gets a random school which has a valid user record. The outer select selects on that school record and sorts by success / attempts and limits to one. Tested with your data.
SELECT s.id, s.name, users.username, users.successes, users.attempts
FROM ((SELECT schools.id, schools.name from schools INNER JOIN users on schools.id = users.school
WHERE users.attempts !=0
ORDER BY RAND()
LIMIT 1) s)
INNER JOIN users on s.id = users.school
ORDER BY users.successes / users.attempts DESC
LIMIT 1
Upvotes: 3