Need to get all referrals ID with using MYSQL
I having a referral table like below.
> id referredByID referrerID
>
> 1001 1 2
>
> 1002 2 3
>
> 1003 2 4
>
> 1004 5 7
From the above table structure i need to get the users whom i referred and the users whom are referred by their referrals.
For Example:
I am referredByID-1
I referred the ID - 2
Now the ID - 2 referred ID -3
And in the same case ID-2 referred ID - 4
Now my output needs to be look like:
Referrals Done By Me:
id - 2
id - 3
id - 4
H开发者_运维问答ow can this be done using MYSQL.
Any help will be appreciated.. Thanks in advance...
I think I got everything the right way round but your naming conventions confused me so you'd better check everything.
If I call the following stored procedure:
call referrals_hier(1);
I get the following results:
+--------------+------------+-------+
| referredByID | referrerID | depth |
+--------------+------------+-------+
| 1 | 2 | 0 |
| 2 | 3 | 1 |
| 2 | 4 | 1 |
+--------------+------------+-------+
3 rows in set (0.00 sec)
full script here: http://pastie.org/1466596
Stored procedure
drop table if exists referrals;
create table referrals
(
id smallint unsigned not null primary key,
referrerID smallint unsigned not null,
referredByID smallint unsigned null,
key (referredByID)
)
engine = innodb;
insert into referrals (id, referredByID, referrerID) values
(1001,1,2),(1002,2,3),(1003,2,4),(1004,5,7);
drop procedure if exists referrals_hier;
delimiter #
create procedure referrals_hier
(
in p_refID smallint unsigned
)
begin
declare v_done tinyint unsigned default(0);
declare v_dpth smallint unsigned default(0);
create temporary table hier(
referredByID smallint unsigned,
referrerID smallint unsigned,
depth smallint unsigned
)engine = memory;
insert into hier select referredByID, referrerID, v_dpth from referrals where referredByID = p_refID;
/* http://dev.mysql.com/doc/refman/5.0/en/temporary-table-problems.html */
create temporary table tmp engine=memory select * from hier;
while not v_done do
if exists( select 1 from referrals e inner join hier on e.referredByID = hier.referrerID and hier.depth = v_dpth) then
insert into hier select e.referredByID, e.referrerID, v_dpth + 1
from referrals e inner join tmp on e.referredByID = tmp.referrerID and tmp.depth = v_dpth;
set v_dpth = v_dpth + 1;
truncate table tmp;
insert into tmp select * from hier where depth = v_dpth;
else
set v_done = 1;
end if;
end while;
select * from hier order by depth;
drop temporary table if exists hier;
drop temporary table if exists tmp;
end #
delimiter ;
-- call this sproc from your php
call referrals_hier(1);
Hope this helps :)
There are two ways, both described here with examples:
http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
These are the cases where MySQL's lack of support for recursive common table expressions really hurts.
If you have an upper limit on the levels, then you might be able to do this with several self joins:
SELECT l1.referredID, l2.referredID, ... FROM your_table l1 LEFT JOIN your_table l2 ON l2.referredByID = l1.referredID LEFT JOIN your_table l3 ON l3.referredByID = l2.referredID LEFT JOIN your_table l4 ON l4.referredByID = l3.referredID ... (you get the picture)
Now as you can see this gets ugly when having more levels and also will not perform very well for larger sets.
If you cannot change your table design then I would suggest to make a good guess on the maximum depth that you can have and create a view that will retrieve all levels. At least that makes it easier in the application or for ad-hoc queries.
On top of that (huge self join) view, you can also build another view that returns each level as its own row. But that will be even slower.
But as long as you deal with MySQL the best thing to do is to change the table design to use the nested set model which is described in the link to the MySQL manual that Anonymous87 has posted.
精彩评论