按推荐人排序(相当复杂)

发布于 2024-09-15 12:13:21 字数 1135 浏览 7 评论 0原文

在这种困境中,我将尽力简洁且充分地解释。

在我管理的网站上,我们允许经理查看他们的“招聘下线”,其中包含他们亲自招募的所有代理的列表,以及特定代理(等等)为团队带来的新成员。

例如:

  • 我招募了两个特工,A和B。A
  • 招募了两个特工,C和D。B
  • 招募了两个特工,E和F。D
  • 招募了两个特工G和H。C
  • 、E和F什么都不做。

alt text

在数据库中,每个单独的代理记录都有一个“推荐代理”字段,其中列出了他们招募的代理。

  • 作为顶层,当我单击“我的 新兵”,我看到了所有人员的名单 子代理(因为他们都跌倒了) 在我的伞下)。
  • A 可以查看 C、D、G 和 H。B
  • 只能查看 E 和 F 他们是他唯一的下线招募者 他们没有带任何人上来 木板。

虽然此功能运行良好,但由于以下两个原因存在缺陷:

由于我们的 PHP 脚本的构建方式,我们无法对整个佣金级别数据进行排序。示例:即使高层和我可以看到每个人,按“佣金级别”排序也会按标准对我的直接代理进行排序,然后将他们的下线作为一个项目进行排序,然后根据我的标准继续进行排序。这很难理解,因此为了演示,假设下表显示所有代理的“佣金级别”:

  • A、7
  • B、6
  • C、5
  • D、6
  • E、5
  • F、2
  • G、5
  • H、1

注意:特工永远不能招募比他们所在级别更高的其他特工,但他们可以招募低于他们的任何级别(例如,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 上线代理编号来确定下一个排队的人。

我知道这“非常”难以理解,但如果我可以对我们当前的“排序”问题提供任何额外的理解,请告诉我。

I will try my best to be both succinct and fully explanatory in this predicament.

On a site I manage, we allow a manager to view their "Recruiting Downline" which entails a list of all agents they personally recruited, as well as the recruits that particular agent (and so on and so on) brought to the Team.

For example:

  • I recruit two Agents, A and B.
  • A recruits two agents, C and D.
  • B recruits two agents, E and F.
  • D recruits two agents G and H.
  • C, E, and F do nothing.

alt text

In the database, every individual agent record has a field for 'referring agent', which lists their recruited agent.

  • As the top level, when I click "My
    Recruits", I am shown a list of all
    sub agents (because they ALL fall
    under my umbrella).
  • A is able to view C, D, G, and H.
  • B is only able to view E and F as
    they are his only downline recruits
    and they have brought nobody on
    board.

While this functionality works great it is flawed for two reasons:

Because of the way our PHP scripts are built, we are unable to sort the commission level data as a whole. Example: Even as the top man and I can see everybody, sorting by 'commission level' sorts my immediate agents by the criteria, then their downline as an item, then continues the sort based on my criteria. This is difficult to understand so to demonstrate, assume the table below displays the 'commission level' for ALL agents:

  • A, 7
  • B, 6
  • C, 5
  • D, 6
  • E, 5
  • F, 2
  • G, 5
  • H, 1

Note: an agent can NEVER recruit another agent at a higher level than they sit but they can recruit at ANY level below them (e.g. a 7 can recruit at 1,2,3,4,5,6 while a 3 can only recruit a 1,2).

FROM MY (high level) perspective,

While it would make sense for the data to be 'sorted by commission level' as:
A, D, B, G, C, E, F, H - this is not the case.

Instead (view from top agent's perspective mind you) is:
A, D, G, H, C, B, E, F

basically, every while loop depends on the DIRECT upline agent number to determine who falls next in line.

I understand this is 'very' difficult to understand but let me know if I can provide any additional understanding into our current 'sort' issue.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浮云落日 2024-09-22 12:13:21

我想我理解你。您想要按给定代理层次结构中的commission_level 进行排序。以下内容可能会有所帮助(http://pastie.org/1111097

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);
*/

i think i understood you. you want to sort by commission_level within a given agent hierarchy. the following may help (http://pastie.org/1111097)

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);
*/
百思不得你姐 2024-09-22 12:13:21

听起来您正在尝试在数据库中实现类似树的结构。您是否考虑过使用 Celko 树:

http://mikehillyer.com/articles /managing-hierarchical-data-in-mysql/

就个人而言,我希望在数据库中实现此类项目的大部分排序和选择方面。请注意,Celko 树并不真正适合非常大的数据集。

Sounds like you're trying to implement tree like structures in your DB. Have you considered using using Celko trees:

http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

Personally, I'd look to implement most of the ordering, selecting aspects of this kind of project in the DB. Note that Celko trees aren't really suitable for very large datasets.

洛阳烟雨空心柳 2024-09-22 12:13:21

所以问题是你没有将“佣金级别”(我认为是距离< ∞的节点数)存储在数据库中?

您有两个选择:

  • 更改您的架构,以便可以轻松检索。请参阅本文
  • 如果它不是一个选项,则仅使用 MySQL 中的 SQL 来计算它可能是不可能的,因为您没有迭代查询(WITH RECURSIVE 子句)。您必须在 PHP 中进行多个查询。

So the problem is that you don't store the "commission level" (which I take to be the number of nodes whose distance is < ∞) in the database?

You have two options:

  • Change your schema so that this is easily retrievable. See this article.
  • If it's not an option calculating it using only SQL in MySQL may not be possible because you don't have iterative queries (WITH RECURSIVE clause). You have to make multiple queries in PHP.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文