我改变了问题的标题,以更好地满足整体需求。我目前有一张表,其中包含我的卖家ID,他们各自的父母ID,他们的佣金水平,他们销售的产品总数以及这些产品的总佣金(在案例陈述中计算,因为佣金因产品而异);但我继续遇到的问题是:
我无法横向查询我的查询结果并计算每个卖家应该收到的子佣金,这是因为他们的下线卖家(他们已经将佣金水平低于他们的卖家)。
我有一个目前“有效”的脚本,但是有近3600行代码,并且在一个脚本中完成了超过50个数据库调用。根据我的经验,没有办法真正“循环”脚本并最小化它,因为每次调用数据库之前都是基于引用ID的子查询。
也许我可以给出一个非常简单的例子,说明我想要完成什么,看看是否有人有类似的经历。
在我的例子中,有三个表:
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将确定他销售的每种产品的佣金百分比,父母表示招募该特定代理商的ID。 在上面的例子中,1是最高级代理人,他招募了两名代理人,2名和3名.2名招募了两名代理人,4名和5名.3名招募了一名代理人,6名。注意:代理人不得招募任何等于或高于他们的人。自己的水平。
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级,他将在每件商品1上获得50%,在每件商品上获得40%2,每个商品获得30%第3项等等。
ID | Item
---------------------
4 | item_1
4 | item_2
1 | item_1
2 | item_3
6 | item_2
1 | item_3
此表格将售出的实际商品与销售商品的卖家配对。
生成佣金报告时,计算个别值非常简单。然而,根据子经销商计算佣金非常困难。
在此示例中,卖家ID 1获得每件商品的一部分。佣金百分比表示个人销售额或佣金高度。
例如:
当卖家ID 6卖出上述第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循环中的DB调用)。
过去有人提出过很好的建议或样本吗?
注意:此示例中的佣金是剩余的,这意味着如果卖方在第1个月登上客户,他/她将收到该客户的相同佣金,直到他们不再是订户为止。
答案 0 :(得分:1)
使用抽象(函数和类)来隐藏数据库访问。这使您在编写计算佣金的算法时更加简洁。此外,它允许您重用早期数据库查询的结果。最后,物品售出表上的一个循环应该足够,填写实际卖家和所有祖先的佣金。理想情况下,每个卖家只能在数据库中读取一次,无论是在前面还是在运行中。
答案 1 :(得分:1)
这可能有助于您入门......
-- 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());