【问题标题】:How to transverse Upward through MySQL prepared statement to calculate Hierarchial Commissions如何通过 MySQL 准备好的语句横向向上计算层次佣金
【发布时间】:2011-05-30 02:28:02
【问题描述】:

更新**:

我更改了问题的标题以更好地满足整体需求。我目前有一个表格,其中包含我的卖家 ID、他们各自的父 ID、他们的佣金水平、他们已售出的产品总和以及这些产品的总佣金(在案例说明中计算,因为佣金因产品而异);但我继续遇到的问题是:

然后,我无法将我的查询结果横向向上计算,并计算每个卖家应该从他们的下线卖家(他们以低于他们的佣金水平引入的卖家)获得的分佣金。




原帖:

我有一个脚本,它目前“有效”,但有近 3600 行代码,并且在单个脚本中进行了超过 50 次数据库调用。根据我的经验,没有办法真正“循环”脚本并将其最小化,因为对数据库的每次调用都是基于引用 id 的先前调用的子查询。

也许我可以举一个非常简单的例子来说明我正在努力完成的事情,看看是否有人有类似的经验。

在我的示例中,有三个表:

表 1 - 卖家

ID       |   Comm_level   |   Parent
-----------------------------------
1        |        4       |   NULL
2        |        3       |   1
3        |        2       |   1
4        |        2       |   2
5        |        2       |   2
6        |        1       |   3

其中 ID 是我们其中一位销售代理的 ID,comm_level 将确定他销售的每种产品的佣金百分比,parent 表示为其招募该特定代理的 ID。 在上面的示例中,1 是顶级特工,他招募了两名特工,2 和 3。2 招募了两名特工,4 和 5。3 招募了一名特工,6。注意:特工永远不能招募等于或高于他们的人自己的水平。

表 2 - 佣金

Level    |    Item 1    |     Item 2     |    Item 3
-----------------------------------------------------
4        |      .5      |       .4       |      .3    
3        |      .45     |       .35      |      .25    
2        |      .4      |       .3       |      .2    
1        |      .35     |       .25      |      .15 

此表列出了每个代理基于其实际 comm_level 的佣金百分比(如果代理处于 4 级,他将获得每售出一件商品 50%、每售出一件商品 40%、每件商品 30%第 3 项,依此类推。

表 3 - 已售商品

      ID     |      Item
   ---------------------
       4     |     item_1
       4     |     item_2
       1     |     item_1
       2     |     item_3
       6     |     item_2
       1     |     item_3

此表将实际出售的商品与出售该商品的卖家配对。

生成佣金报告时,计算单个值非常简单。然而,根据他们的 sub_sellers 计算他们的佣金是非常困难的。

在本例中,卖家 ID 1 会从每件售出的商品中分得一件。佣金百分比表示个人销售额或佣金的高度。

例如:

当卖家 ID 6 出售上述 item_2 之一时,佣金树将如下所示:

-ID 6 - 成本的 25%(item_1)

-ID 3 - 成本的 5%(item_1) - (30% 是他的通讯 - 卖家 ID 6 的 25% 通讯)

-ID 1 - 成本的 10%(item_1) - (40% 是他的通讯 - 卖家 ID 3 的 30%)

这必须为系统中的每个代理从上到下计算(因此数据库在我的巨大脚本中的 while 循环中调用)。

任何人有他们过去可能使用过的好建议或示例?

修改佣金结构

注意:本例中的佣金是剩余的,这意味着如果卖家在第 1 个月加入客户,他/她将为该客户收到相同的佣金,直到他们不再是订阅者。

【问题讨论】:

    标签: php mysql pdo


    【解决方案1】:

    使用抽象(函数和类)来隐藏数据库访问。这使您在编写计算佣金的算法时更加简洁。此外,它允许您重用早期数据库查询的结果。最后,在 Items Sold 表上循环一圈就足够了,填写实际卖家和所有祖先的佣金。理想情况下,每个卖家只能从数据库中读取一次,无论是预先还是在运行中。

    【讨论】:

      【解决方案2】:

      这可能有助于您开始...

      -- TABLES
      
      drop table if exists seller;
      create table seller
      (
      seller_id int unsigned not null auto_increment primary key,
      comm_level tinyint unsigned default 0,
      parent_seller_id int unsigned default null,
      key (parent_seller_id)
      )
      engine = innodb;
      
      insert into seller (comm_level, parent_seller_id) values
      (4,null),
       (3,1),
       (2,1),
          (2,2),
          (2,2),
              (1,3);
      
      -- STORED PROCEDURES
      
      drop procedure if exists seller_commissions_hier;
      delimiter #
      
      create procedure seller_commissions_hier
      (
      in p_seller_id int unsigned,
      in p_start_date date,
      in p_end_date date
      )
      proc_main:begin
      
      declare done tinyint unsigned default 0;
      declare dpth smallint unsigned default 0;
      
      drop temporary table if exists hier;
      drop temporary table if exists tmp;
      
      create temporary table hier(
       parent_seller_id int unsigned, 
       seller_id int unsigned not null, 
       depth smallint unsigned not null default 0,
       comm_level tinyint unsigned not null default 0,
       sales decimal(10,2) not null default 0,
       commission decimal(10,2) not null default 0
      )
      engine = memory;
      
      -- step1. work out the hierarchy with sales and commission set to 0
      
      insert into hier select parent_seller_id, seller_id, 0, comm_level, 0 as sales, 0 as commission
       from seller where seller_id = p_seller_id;
      
      /* http://dev.mysql.com/doc/refman/5.0/en/temporary-table-problems.html */
      
      create temporary table tmp engine=memory select * from hier;
      
      while not done do
      
          if exists( select 1 from seller s inner join hier on s.parent_seller_id = hier.seller_id and hier.depth = dpth) then
      
              insert into hier 
                  select s.parent_seller_id, s.seller_id, dpth + 1, s.comm_level, 0, 0 from seller s
                  inner join tmp on s.parent_seller_id = tmp.seller_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;
      
      -- step 2. update the hier table with sales totals for period you are interested in for each seller (to do)
      
      -- (hint: use a derived table to calculate total sales for period grouped by seller_id and join back to hier for the update)
      
      -- step 3. work out commissions based on sales and comm_level for each seller (to do)
      
      -- (sure you can work this out)
      
      -- step 4. output the results
      
      select 
       s.seller_id,
       p.seller_id as parent_seller_id,
       hier.depth,
       hier.comm_level,
       hier.sales,
       hier.commission
      from 
       hier
      inner join seller s on hier.seller_id = s.seller_id
      left outer join seller p on hier.parent_seller_id = p.seller_id
      order by
       hier.depth, hier.seller_id; 
      
      drop temporary table if exists hier;
      drop temporary table if exists tmp;
      
      end proc_main #
      
      delimiter ;
      
      -- TESTING
      
      call seller_commissions_hier(1, now() - interval 1 month, now());
      
      call seller_commissions_hier(2, now() - interval 1 month, now());
      

      【讨论】:

      • 感谢您的建议。实际上,我的故事板与您提出的相同建议相似,但我面临的问题甚至不一定与在个人级别上使用销售/佣金数据填充层次表有关,而是如何循环并计算卖家将收到的额外佣金如果他/她有下线(招募)卖家。
      • 啊-您可能需要一个额外的临时层次结构来帮助计算...会有想法但会暂时停止 :)
      • 同意。到目前为止,我已经将表格准确地列出了我觉得我需要它的方式(我们所有的想法与代理商列出的总销售额和总个人佣金相结合)但是构建脚本以横向备份计算子树的树是很棘手的- 必要时的佣金。我会继续玩弄,但如果您有任何建议,非常感谢。另外 - 给你发了一封电子邮件,基本上是关于同样的概念 - 没有收到回复!
      • @JM4 - 很抱歉在节日期间检查电子邮件有点慢 - 会看看... :)
      猜你喜欢
      • 1970-01-01
      • 2011-09-16
      • 1970-01-01
      • 2012-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多