我将尽力在这种困境中既简洁又完全解释。
在我管理的网站上,我们允许经理查看他们的“招募下线”,其中包含他们个人招募的所有代理商的列表,以及特定代理商(等等)带来的新员工。球队。
例如:
在数据库中,每个代理记录都有一个“推荐代理人”字段,其中列出了他们的招募代理人。
虽然这个功能很有效,但它存在缺陷有两个原因:
由于构建PHP脚本的方式,我们无法整体调整佣金级别数据。示例:即使作为顶级人员和我可以看到所有人,按“佣金级别”排序按标准对我的直接代理进行排序,然后将其下线作为项目,然后根据我的标准继续排序。这很难理解,为了证明这一点,假设下表显示了所有代理商的“佣金水平”:
注意:代理人永远不能在比他们所处的更高级别招募另一名代理人,但他们可以在他们以下的任何级别招募(例如,7人可以在1,2,3,4,5,6招募,而3人可以只招募1,2)。
虽然将数据“按佣金水平排序”是有意义的: A,D,B,G,C,E,F,H - 情况并非如此。
相反(从顶级经纪人的角度来看,请注意): A,D,G,H,C,B,E,F
基本上,每个while循环都依赖于DIRECT上线代理号来确定谁下一个排队。
我理解这是“非常”难以理解,但如果我能对我们当前的“排序”问题提供任何其他理解,请告诉我。
答案 0 :(得分:1)
听起来你正试图在数据库中实现树状结构。你考虑过使用Celko树吗?
http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
就个人而言,我希望实现大部分订购,在数据库中选择此类项目的各个方面。请注意,Celko树不适合非常大的数据集。
答案 1 :(得分:1)
drop table if exists agent;
create table agent
(
agent_id int unsigned not null auto_increment primary key,
name varchar(32) not null,
commission_level tinyint unsigned default 0,
parent_agent_id int unsigned default null
)
engine = innodb;
insert into agent (name, commission_level, parent_agent_id) values
('I', 99, null),
('A', 7, 1),
('B', 6, 1),
('C', 5, 2),
('D', 6, 2),
('E', 5, 3),
('F', 2, 3),
('G', 5, 5),
('H', 1, 5);
delimiter ;
drop procedure if exists agent_hier;
delimiter #
create procedure agent_hier
(
in p_agent_id int unsigned
)
proc_main:begin
declare done tinyint unsigned default 0;
declare dpth smallint unsigned default 0;
create temporary table hier(
parent_agent_id int unsigned,
agent_id int unsigned,
depth smallint unsigned default 0
)engine = memory;
insert into hier values (p_agent_id, p_agent_id, dpth);
/* http://dev.mysql.com/doc/refman/5.0/en/temporary-table-problems.html */
create temporary table tmp engine=memory select * from hier;
while done <> 1 do
if exists( select 1 from agent a inner join hier on a.parent_agent_id = hier.agent_id and hier.depth = dpth) then
insert into hier
select a.parent_agent_id, a.agent_id, dpth + 1 from agent a
inner join tmp on a.parent_agent_id = tmp.agent_id and tmp.depth = dpth;
set dpth = dpth + 1;
truncate table tmp;
insert into tmp select * from hier where depth = dpth;
else
set done = 1;
end if;
end while;
select
a.agent_id,
a.name as agent_name,
if(a.agent_id = b.agent_id, null, b.agent_id) as parent_agent_id,
if(a.agent_id = b.agent_id, null, b.name) as parent_agent_name,
hier.depth,
a.commission_level
from
hier
inner join agent a on hier.agent_id = a.agent_id
inner join agent b on hier.parent_agent_id = b.agent_id
order by
-- dont want to sort by depth but by commision instead - i think ??
-- hier.depth, hier.agent_id;
a.commission_level desc;
drop temporary table if exists hier;
drop temporary table if exists tmp;
end proc_main #
delimiter ;
/*
select * from agent;
call agent_hier(1);
call agent_hier(2);
call agent_hier(3);
call agent_hier(5);
*/
答案 2 :(得分:0)
所以问题是你没有在数据库中存储“佣金级别”(我认为它是距离<∞的节点数)?
您有两种选择:
WITH RECURSIVE
子句)。您必须在PHP中进行多个查询。