本帖最后由 frankonlyfine 于 2010-10-21 10:06:42 编辑

解决方案 »

  1.   

     (不要高估你的汉语表达能力或者我的汉语理解能力)
       建议你列出你的表结构,并提供测试数据以及基于这些测试数据的所对应正确结果。
       参考一下这个贴子的提问方式http://topic.csdn.net/u/20091130/20/8343ee6a-417c-4c2d-9415-fa46604a00cf.html
       
       1. 你的 create table xxx .. 语句
       2. 你的 insert into xxx ... 语句
       3. 结果是什么样,(并给以简单的算法描述)
       4. 你用的数据库名称和版本(经常有人在MS SQL server版问 MySQL)
       
       这样想帮你的人可以直接搭建和你相同的环境,并在给出方案前进行测试,避免文字描述理解上的误差。   
      

  2.   

    1. 从哪一条开始找?
    2. balance字段更新为什么?全部更新为数字1行不行?
      

  3.   

    1。就从ID=5的开始找,一条条找上去直到parentid=0为止2,不行,因为balance的值都是不一样的,根据层级数来更新balance的比例,比如说id=4的是id=5的上一级(因为它parentid=4),就是总额的40%,然后上上一层是30%这样注:这个过程会传两个值,一个是ID,一个是总额。比如说我传入两个值5(ID),1000(总额)
      

  4.   

    按照一楼,提供你的 create table , insert into 语句,这样别人可以直接测试, 
    另外 按照你的例子。 传入两个值5(ID),1000(总额)
    期望的结果是什么? 下面是你想要的结果吗?id      parentid     balance
    1                     0                     100
    2                     1                     200
    3                     2                     300
    4                     3                     400
    5                     4                      1000
    问题说明越详细,回答也会越准确!参见如何提问。(提问的智慧
      

  5.   

    嗯这样可以  是我想要的结果insert就不做了。就先拿这五条固定数据做测试要不我提供下我写的测试存储过程,这中间好像有个BUG,没有循环更新balance值。但我看了代码又好像没觉得哪有问题
    drop PROCEDURE if exists test;
    CREATE PROCEDURE  test()
    begin
    declare i integer default 10;
    declare d_pid int default 0;
    declare d_pid_in int default 0;
    declare str_temp varchar(40) default '';select `parentid` into d_pid from tgy_members where id=4;
    update tgy_members set balance=100 where id=4; #上一级loop1: LOOP
    begin
    select `parentid` into d_pid_in from tgy_members where id=d_pid;
    set str_temp = concat(str_temp,d_pid);

    if(d_pid_in = 0) then
                   set str_temp = concat(str_temp,d_pid_in);
    update tgy_members set balance=i where id=d_pid_in;

    leave loop1;
    else
    set str_temp = concat(str_temp,d_pid_in);

    update tgy_members set balance=i where id=d_pid_in;
    select `parentid` into d_pid from tgy_members where id=d_pid_in;
    end if;
    set i=i+1;

    end;
    END LOOP loop1;  
    select str_temp;end
    我测试时没有传参数,然后balance值先没按比例去弄。主要是先把循环update解决
      

  6.   

    update tgy_members set balance=100 where id=4; #上一级这里应该是id=5 先从5开始
      

  7.   

    我觉得如果MYSQL有GOTO语句就最适合了,如果parentid!=0的话就一直GOTO到前面的语句再走下来
      

  8.   

    如果超过5层后怎么办?1000 -> 400 ->300 -> 200 -> 100 -> 0 - > -100 -> -200 ?
      

  9.   

    如果你不方便提供测试用的 create table / insert into 这些语句的,等我有空了,我写一下,贴上来让其它人可以创建相同的测试环境。
      

  10.   


    SET FOREIGN_KEY_CHECKS=0;
    -- ----------------------------
    -- Table structure for tgy_members
    -- ----------------------------
    DROP TABLE IF EXISTS `tgy_members`;
    CREATE TABLE `tgy_members` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `parentId` int(11) DEFAULT NULL,
      `UserName` varchar(30) NOT NULL,
      `UserType` tinyint(4) NOT NULL,
      `TrueName` varchar(30) NOT NULL,
      `TK_Password` varchar(30) DEFAULT NULL,
      `CardNo` varchar(20) DEFAULT NULL,
      `CardPic` varchar(50) DEFAULT NULL,
      `Email` varchar(60) DEFAULT NULL,
      `Phone` varchar(20) DEFAULT NULL,
      `Balance` decimal(10,0) DEFAULT NULL,
      `State` tinyint(4) DEFAULT NULL,
      `CreateTime` datetime DEFAULT NULL,
      `LastTime` datetime DEFAULT NULL,
      `ClickTime` datetime DEFAULT NULL,
      `LoginCount` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`),
      KEY `UserName` (`UserName`),
      KEY `parentId` (`parentId`)
    ) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8;-- ----------------------------
    -- Records 
    -- ----------------------------
    INSERT INTO `tgy_members` VALUES ('1', '0', 'test', '0', 'test', '123', null, null, null, null, '0', null, null, null, null, null);
    INSERT INTO `tgy_members` VALUES ('2', '1', 'test2', '0', 'test', '123', null, null, null, null, '0', null, null, null, null, null);
    INSERT INTO `tgy_members` VALUES ('3', '2', 'test3', '0', 'test', '123', null, null, null, null, '0', null, null, null, null, null);
    INSERT INTO `tgy_members` VALUES ('4', '3', 'test4', '0', 'test', '123', null, null, null, null, '0', null, null, null, null, null);
    INSERT INTO `tgy_members` VALUES ('5', '4', 'test', '0', 'test', null, null, null, null, null, '0', null, null, null, null, null);哦好的,我提供了,你帮我测下看.过程就是那个
      

  11.   


    我只是定5层而已,超过5层是必然的,所以我才说是无限循环。循环到parentid=0为止
      

  12.   

    超过5层后,balance 是什么? -100 ?
      

  13.   

    也可以。balance的值无所谓,我主要是要实现这个循环update~
      

  14.   

    mysql> select id,parentId,UserName,Balance from tgy_members;
    +----+----------+----------+---------+
    | id | parentId | UserName | Balance |
    +----+----------+----------+---------+
    |  1 |        0 | test     |       0 |
    |  2 |        1 | test2    |       0 |
    |  3 |        2 | test3    |       0 |
    |  4 |        3 | test4    |       0 |
    |  5 |        4 | test     |       0 |
    +----+----------+----------+---------+
    5 rows in set (0.00 sec)mysql> drop PROCEDURE x;
    Query OK, 0 rows affected (0.17 sec)mysql> delimiter //
    mysql> CREATE PROCEDURE x(vid int, vAmt int)
        -> begin
        ->  DECLARE i INT default 4;
        ->  update tgy_members set Balance=vAmt where id= vid;
        ->  select parentId into vid from tgy_members where id= vid;
        ->  WHILE vid > 0 DO
        ->          update tgy_members set Balance=vAmt*i/10 where id= vid;
        ->          select parentId into vid from tgy_members where id= vid;
        ->          set i=i-1;
        ->  END WHILE;
        -> end
        -> //
    Query OK, 0 rows affected (0.06 sec)mysql> delimiter ;
    mysql> call x(5,100);
    Query OK, 0 rows affected (0.23 sec)mysql> select id,parentId,UserName,Balance from tgy_members;
    +----+----------+----------+---------+
    | id | parentId | UserName | Balance |
    +----+----------+----------+---------+
    |  1 |        0 | test     |      10 |
    |  2 |        1 | test2    |      20 |
    |  3 |        2 | test3    |      30 |
    |  4 |        3 | test4    |      40 |
    |  5 |        4 | test     |     100 |
    +----+----------+----------+---------+
    5 rows in set (0.00 sec)mysql>
      

  15.   

     DECLARE i INT default 4;你还没明白我的意思,有多少层级关系事先是不知道的,所以不应该有定义i这个值,循环依据以parentid为准, 为0时才结束循环
      

  16.   

     select parentId into vid from tgy_members where id= vid;这下面应该要加个判断if(vid=0) then
           break;
    end if;应该是这样的一个逻辑关系,不过我不知道MYSQL的退出循环怎么写
      

  17.   

    呵呵那如果中间ID为3的那条parentid是0怎么办?你根本就没了解我的需求,还说我没仔细看你代码I起的作用就是循环次数。我已经说过很多次了,有多少层级关系事先是不知道的,你定义个固定的循环次数有什么用,如果要循环的次数是超过了或者是未超过你怎么去结束这段循环呢