Reputation: 906
Here is the scenario. I have different levels of users. the user creation process is like this: admin -> reseller -> marketer -> autoservice
I am trying to write a SQL query to select all autoservices created by a specific reseller. all users are saved in users table which has the following simplified structure:
+----+--------+--------------+-------------+-----------+
| id | userid | username | role | createdby |
+----+--------+--------------+-------------+-----------+
| 1 | 334455 | reseller1 | reseller | admin |
| 2 | 245578 | marketer1 | marketer | reseller1 |
| 3 | 235677 | autoservice1 | autoservice | marketer1 |
| 4 | 253569 | autoservice2 | autoservice | marketer1 |
| 5 | 234267 | autoservice3 | autoservice | marketer1 |
| 6 | 245468 | marketer2 | marketer | reseller1 |
| 5 | 434567 | autoservice4 | autoservice | marketer2 |
| 5 | 532263 | autoservice5 | autoservice | marketer2 |
| 5 | 634262 | autoservice6 | autoservice | marketer2 |
+----+--------+--------------+-------------+-----------+
The query should select autoservice1, autoservice2, autoservice3, autoservice4, autoservice5, autoservice6 and all their fields. currently I'm doing this with a combination of MySQL and php. First I select all marketers created by reseller1:
$sql="SELECT * FROM marketers WHERE createdby=:createdby";
$st=$conn->prepare($sql);
$st->bindvalue(":createdby",'reseller1',PDO::PARAM_STR);
$st->execute();
$usersArray=$st->fetchAll();
$NumberOfusers=$st->rowcount();
Then I loop through the results:
$MembersGeoData=array();
$MembersCount=0;
for($i=0;$i<$NumberOfusers;$i++) {
$sql="SELECT * FROM autoservices WHERE createdby=:createdby";
$st=$conn->prepare($sql);
$st->bindvalue(":createdby",$usersArray[$i]['username'],PDO::PARAM_STR);
$st->execute();
$tempUsersArray=$st->fetchAll();
$tempNumberOfusers=$st->rowcount();
$MembersGeoData=array_merge($MembersGeoData,$tempUsersArray);
$MembersCount+=$tempNumberOfusers;
}
This works but seems to be very inefficient. How can I do this with one sql query?
Upvotes: 0
Views: 124
Reputation: 906
I used The answer from @Gordon Linoff and answered my question :
SELECT a.* FROM autoservices AS a
JOIN marketers AS m
ON a.createdby=m.username
WHERE m.createdby='reseller1'
Upvotes: 0
Reputation: 1269873
Assuming that your hierarchy is exactly correct (it is never skipped and a marketer never creates another marketer), then:
select sa.*
from autoservices sm join
autoservices sa
on sa.role = 'autoservice' and
sm.role = 'marketer' and
sm.username = sa.createdBy
where sm.createdBy = 'reseller1';
You are correct. You should let the database do this work.
Upvotes: 1