本帖最后由 Beirut 于 2010-03-17 19:26:20 编辑

解决方案 »

  1.   

    一个SQL语句无法实现,需要使用程序或者存储过程。
      

  2.   

    程序的我会搞,呵呵麻烦大侠给我写个存储过程。
    也不一顶要一句sql
    只要是sql实现就行
      

  3.   

    select * from tb where id <=(select id from tb a where(select count(id) from tb where id < a.id ) = 4)
    后面的4代表的是你指定那一行的id-1就行了、、
      

  4.   

    select * from tb where id <=(select id from tb a where(select count(id) from tb where id < a.id ) = 4)
    后面的4代表的是你指定那一行的id-1就行了、、
      

  5.   

    select * from tb where id <=(select id from tb a where(select count(id) from tb where id < a.id ) = 4)
    后面的4代表的是你指定那一行的id-1就行了、、
      

  6.   

    如果一定要用一句sql完成,建议楼主改一下表结构,给每条记录加上左右标识,建立树结构,这样可以用一句sql完成你说的功能了
      

  7.   

    1.用递归求出id,并以(‘002’,‘003’,‘010’,。)的格式保存至一个字符串类型变量strID
    2.'select * from tb where id in '+ strID
      

  8.   

    只能加分到100了,帮写个存储过程实现呵,让我学习学习mysql
      

  9.   

    mysql> select * from tb;
    +------+------+--------+
    | id   | pid  | name   |
    +------+------+--------+
    | 001  | NULL | 广东省 |
    | 002  | 001  | 广州市 |
    | 003  | 001  | 深圳市 |
    | 004  | 002  | 天河区 |
    | 005  | 003  | 罗湖区 |
    | 006  | 003  | 福田区 |
    | 007  | 003  | 宝安区 |
    | 008  | 007  | 西乡镇 |
    | 009  | 007  | 龙华镇 |
    | 010  | 007  | 松岗镇 |
    +------+------+--------+
    10 rows in set (0.00 sec)mysql> delimiter //
    mysql>
    mysql> CREATE FUNCTION `getParentLst`(NodeId CHAR(3))
        -> RETURNS varchar(1000)
        -> DETERMINISTIC
        -> -- READS SQL DATA
        -> BEGIN
        ->   DECLARE sTemp VARCHAR(1000);
        ->   DECLARE sTempChd VARCHAR(1000);
        ->
        ->   SET sTemp = '$';
        ->   set sTempChd=NodeId;
        ->    label1: LOOP
        ->      SET sTemp = concat(sTemp,',',sTempChd);
        ->      SELECT pid INTO sTempChd FROM tb where id=sTempChd;
        ->      IF FOUND_ROWS()=0 or sTempChd is null THEN
        ->          RETURN sTemp;
        ->      END IF;
        ->    END LOOP label1;
        ->   RETURN sTemp;
        -> END
        -> //
    Query OK, 0 rows affected (0.00 sec)mysql> delimiter ;
    mysql> select getParentLst('010');
    +---------------------+
    | getParentLst('010') |
    +---------------------+
    | $,010,007,003,001   |
    +---------------------+
    1 row in set (0.00 sec)mysql> select * from tb
        -> where find_in_set(id , getParentLst((select id from tb where name='松岗镇') ));
    +------+------+--------+
    | id   | pid  | name   |
    +------+------+--------+
    | 001  | NULL | 广东省 |
    | 003  | 001  | 深圳市 |
    | 007  | 003  | 宝安区 |
    | 010  | 007  | 松岗镇 |
    +------+------+--------+
    4 rows in set (0.00 sec)mysql> select * from tb
        -> where find_in_set(id , getParentLst((select id from tb where name='宝安区') ));
    +------+------+--------+
    | id   | pid  | name   |
    +------+------+--------+
    | 001  | NULL | 广东省 |
    | 003  | 001  | 深圳市 |
    | 007  | 003  | 宝安区 |
    +------+------+--------+
    3 rows in set (0.02 sec)mysql>
      

  10.   


    可能我没说清楚,fyi,借用你的表结构直接改在下面了:
    create table tb(id varchar(3) , pid varchar(3) , name varchar(10) , 
                    left_point  int(10) , right_point int(10)) 
    insert into tb values('001' , null  , '广东省' , 1 , 20) ;
    insert into tb values('002' , '001' , '广州市' , 2 , 5) ;
    insert into tb values('003' , '001' , '深圳市' , 6 , 19) ;
    insert into tb values('004' , '002' , '天河区' , 3 , 4) ;
    insert into tb values('005' , '003' , '罗湖区' , 7 , 8) ;
    insert into tb values('006' , '003' , '福田区' , 9 , 10) ;
    insert into tb values('007' , '003' , '宝安区' , 11 , 18) ;
    insert into tb values('008' , '007' , '西乡镇' , 12 , 13) ;
    insert into tb values('009' , '007' , '龙华镇' , 14 , 15) ;
    insert into tb values('010' , '007' , '松岗镇' , 16 , 17) ;如果这样的话你的需求就一句sql:
    --指定部门为“松岗镇”
    select * 
    from tb A, tb B 
    where B.name = '松岗镇' 
      and A.left_point < B.left_point 
      and A.right_poing > B.right_poing--如果指定部门为“宝安区”
    select * 
    from tb A, tb B 
    where B.name = '宝安区' 
      and A.left_point < B.left_point 
      and A.right_poing > B.right_poing当然这个方法的缺点是在建立表和增减表内记录时比较麻烦
      

  11.   

    select * from tb
    create table tb(id varchar(3) , pid varchar(3) , name varchar(10))
    insert into tb values('001',null, '广东省')
    insert into tb values('002' , '001' , '广州市')
    insert into tb values('003' , '001' , '深圳市')
    insert into tb values('004' , '002' , '天河区')
    insert into tb values('005' , '003' , '罗湖区')
    insert into tb values('006' , '003' , '福田区')
    insert into tb values('007' , '003' , '宝安区')
    insert into tb values('008' , '007' , '西乡镇')
    insert into tb values('009' , '007' , '龙华镇')
    insert into tb values('010' , '007' , '松岗镇')
    go--查询指定节点及其所有父节点的函数
    create function f_pid(@id varchar(3)) returns @t_level table(id varchar(3))
    as
    begin
      insert into @t_level select @id
      select @id = pid from tb where id = @id and pid is not null
      while @@ROWCOUNT > 0
      begin
        insert into @t_level select @id 
        select @id = pid from tb where id = @id and pid is not null
      end
      return
    end
    go 
    --调用函数查询002(广州市)及其所有父节点
    select * from tb
    select a.* from tb a , f_pid('004') b where a.id = b.id order by a.id
    /*
    id   pid  name       
    ---- ---- ---------- 
    001  NULL 广东省
    002  001  广州市(所影响的行数为 2 行)
    */--调用函数查询003(深圳市)及其所有父节点
    select a.* from tb a , f_pid('003') b where a.id = b.id order by a.id
    /*
    id   pid  name       
    ---- ---- ---------- 
    001  NULL 广东省
    003  001  深圳市(所影响的行数为 2 行)
    */--调用函数查询008(西乡镇)及其所有父节点
    select a.* from tb a , f_pid('008') b where a.id = b.id order by a.id
    /*
    id   pid  name       
    ---- ---- ---------- 
    001  NULL 广东省
    003  001  深圳市
    007  003  宝安区
    008  007  西乡镇(所影响的行数为 4 行)
    */drop table tb
    drop function f_pid