请教一个SQL查询语句写法。。BANJI 表为班级 字段:ID , NIANJI_ID(年级ID) , NAME
NIANJI 表为年级 字段:ID , XUEXIAO_ID(学校ID) , NAME
XUEXIAO 表为学校 字段: ID , NAMESTU表为学生总表 字段 :ID , LZ_TYPE(有三个值的可能BNAJI_ID,NIANJI_ID,XUEXIAO_ID) , LZ_ID(与LZ_TYPE对应,填写年级ID,学校ID或地区ID的值) , NAME现希望查询所有学生表及其地区
即D.* , XUEXIAO.ID不知道我表达清楚没有,希望高手指点。

解决方案 »

  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.   

    STU表这种设计方法确实不太好
    应该是这样的:ID,XUEXIAO_ID,NIANJI_ID,BANJI_ID,NAME
      

  3.   

    对不起大家了,其实原表不是这样,很多字段,我只把关键的列出来了大家不清楚是我的表达能力的问题。。我再试一次哦。!
    其实就是四个表:
    一个是班级表,有一个字段对应年级ID,代表它从属于哪个年级,另外有自己的ID,NAME
    一个是年级表,有一个字段对应学校ID,代表它从属于哪个学校,另外有自己的ID,NAME
    一个是学校表,有自己的ID,NAME
    一个是学生表,他有自己的ID,NAME ,同时有两个字段表明他来自哪里,但不一定存贮的是班级ID,可能直接是年级ID或学校ID,因此,这两个字段是
    LZ_TYPE,值是“BNAJI_ID”或“NIANJI_ID”或“XUEXIAO_ID”
    LZ_ID,如果LZ_TYPE值是“BNAJI_ID”,这里存贮的就是班级ID
           如果LZ_TYPE值是“NIANJI_ID”,这里存贮的就是年级ID
           如果LZ_TYPE值是“XUEXIAO_ID”,这里存贮的就是学校ID
    最后希望求出所有学生属于的学校如下:
    create table BANJI
    (
    ID int,
    NAME varchar(20),
    NIANJI_ID int
    )
    insert into BANJI select 1,'美术班',1
    insert into BANJI select 2,'数学班',2create table NIANJI
    (
    ID int,
    NAME varchar(20),
    XUEXIAO_ID int
    )
    insert into NIANJI select 1,'一年级',1
    insert into NIANJI select 2,'二年级',2create table XUEXIAO
    (
    ID int,
    NAME varchar(20)
    )
    insert into XUEXIAO select 1,'东门小学'
    insert into XUEXIAO select 2,'宝塔中学'create table STU
    (
    ID int,
    NAME varchar(20),
    LZ_TYPE varchar(20),
    LZ_ID int
    )
    insert into STU select 1,'张学友','BANJI_ID',1
    insert into STU select 2,'刘德华','BANJI_ID',2
    insert into STU select 3,'黎明','NIANJI_ID',1
    insert into STU select 4,'郭富城','NIANJI_ID',2
    insert into STU select 5,'天山童姥','XUEXIAO_ID',1
    insert into STU select 6,'李秋水','XUEXIAO_ID',2/*
    要得到这样的报表:
    STU.ID STU.NAME XUEXIAO.NAME
    1      张学友   东门小学
    2      刘德华   宝塔中学
    3      黎明     东门中学
    4      郭富城   宝塔中学
    5      天山童姥 东门中学
    6      李秋水   宝塔中学
    */
      

  4.   

    楼主问的是MYSQL还是SQL SERVER ?
      

  5.   

    mysql> select STU.ID,STU.NAME,XUEXIAO.NAME
        -> from stu,xuexiao
        -> where stu.LZ_ID=xuexiao.ID;
    +------+----------+----------+
    | ID   | NAME     | NAME     |
    +------+----------+----------+
    |    1 | 张学友   | 东门小学 |
    |    2 | 刘德华   | 宝塔中学 |
    |    3 | 黎明     | 东门小学 |
    |    4 | 郭富城   | 宝塔中学 |
    |    5 | 天山童姥 | 东门小学 |
    |    6 | 李秋水   | 宝塔中学 |
    +------+----------+----------+
    6 rows in set (0.03 sec)mysql>
      

  6.   

    是MYSQL,可能测试数据太少了。LZ_ID里有的是NIANJI_ID,有的是BANJI_ID不一定都是XUEXIAO_ID哦
      

  7.   

    贴出测试 数据,这个 要用SP来完成
    示例,自行修改
    DELIMITER $$USE `test`$$DROP PROCEDURE IF EXISTS `PD`$$CREATE DEFINER=`root`@`localhost` PROCEDURE `PD`()
    BEGIN
    DECLARE done INT DEFAULT 0;
    DECLARE BTYPE CHAR(20);
    DECLARE cur1 CURSOR FOR SELECT DISTINCT LZ_TYPE FROM STU;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
    OPEN cur1;
    SET @ASQL='';
      FETCH cur1 INTO BTYPE;
        WHILE done=0 DO
    SET @ASQL=CONCAT(@ASQL,'SELECT * FROM STU A LEFT JOIN ',REPLACE(BTYPE,'_ID',''),' B ON A.LZ_ID=B.',BTYPE,' WHERE A.LZ_TYPE=\'',BTYPE,'\' UNION ') ;
      FETCH cur1 INTO BTYPE;
       END WHILE;
     SELECT LEFT(@ASQL,LENGTH(@ASQL)-7);
     SET @ASQL=LEFT(@ASQL,LENGTH(@ASQL)-7);
     PREPARE stmt1 FROM @ASQL;
     EXECUTE stmt1 ;
     DEALLOCATE PREPARE stmt1;
    END$$DELIMITER ;
      

  8.   

    完了,我不懂楼上这个,这在PHP里咋实现呢?
      

  9.   

    create table BANJI
    (
    ID int,
    NAME varchar(20),
    NIANJI_ID int
    )
    insert into BANJI select 1,'美术班',1
    insert into BANJI select 2,'数学班',2
    insert into BANJI select 3,'语文班',1create table NIANJI
    (
    ID int,
    NAME varchar(20),
    XUEXIAO_ID int
    )
    insert into NIANJI select 1,'一年级',1
    insert into NIANJI select 2,'二年级',2
    insert into NIANJI select 3,'三年级',2create table XUEXIAO
    (
    ID int,
    NAME varchar(20)
    )
    insert into XUEXIAO select 1,'东门小学'
    insert into XUEXIAO select 2,'宝塔中学'create table STU
    (
    ID int,
    NAME varchar(20),
    LZ_TYPE varchar(20),
    LZ_ID int
    )
    insert into STU select 1,'张学友','BANJI_ID',1
    insert into STU select 2,'刘德华','BANJI_ID',2
    insert into STU select 2,'风清扬','BANJI_ID',3
    insert into STU select 4,'黎明','NIANJI_ID',1
    insert into STU select 5,'郭富城','NIANJI_ID',2
    insert into STU select 6,'迈克','NIANJI_ID',3
    insert into STU select 7,'天山童姥','XUEXIAO_ID',1
    insert into STU select 8,'李秋水','XUEXIAO_ID',2/*
    要得到这样的报表:
    STU.ID STU.NAME XUEXIAO.NAME
    1      张学友   东门小学
    2      刘德华   宝塔中学
    3      风清扬   东门小学
    4      黎明     东门小学
    5      郭富城   宝塔中学
    6      迈克     宝塔中学
    7      天山童姥 东门小学
    8      李秋水   宝塔中学
    */这样应该不会有岐义了吧!
      

  10.   

    ELIMITER $$USE `ee`$$DROP PROCEDURE IF EXISTS `PD`$$CREATE DEFINER=`root`@`localhost` PROCEDURE `pd`()
    BEGIN
    DECLARE done INT DEFAULT 0;
    DECLARE BTYPE CHAR(20);
    DECLARE cur1 CURSOR FOR SELECT DISTINCT LZ_TYPE FROM STU;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
    OPEN cur1;
    SET @ASQL='';
    SET @ASQL1='';
      FETCH cur1 INTO BTYPE;
        WHILE done=0 DO
     IF UCASE(BTYPE)='XUEXIAO_ID' THEN
     SET @asql1=CONCAT(@asql1,'select a.ID,a.NAME as sname,b.NAME FROM STU A LEFT JOIN XUEXIAO b on a.LZ_ID=b.id WHERE A.LZ_TYPE=\'XUEXIAO_ID\'');
     ELSE
    SET @ASQL=CONCAT(@ASQL,'SELECT a.*,b.',IF(btype='BANJI_ID','NIANJI_ID','XUEXIAO_ID'),' FROM STU A LEFT JOIN ',REPLACE(BTYPE,'_ID',''),' B ON A.LZ_ID=B.id',' WHERE A.LZ_TYPE=\'',BTYPE,'\' UNION ') ;
    END IF;
      FETCH cur1 INTO BTYPE;
       END WHILE;
     SET @ASQL=CONCAT('SELECT a.ID,a.NAME as sname,c.NAME FROM (',LEFT(@ASQL,LENGTH(@ASQL)-7),') A LEFT JOIN XUEXIAO C ON A.NIANJI_ID=C.ID');
     SET @asql1=CONCAT('select * from (',@asql1,' union all ',@ASQL,') a');
    PREPARE stmt1 FROM @ASQL1;
     EXECUTE stmt1 ;
      DEALLOCATE PREPARE stmt1;
     SELECT @asql1;
    END$$DELIMITER ;call pd()
      

  11.   

    ELIMITER $$->dELIMITER $$
      

  12.   

    楼主显然根本没有看过自己提供的测试用例!问一下楼主,你的这个 3      风清扬   东门小学 哪来的?!mysql> select STU.ID,STU.NAME,t.NAME
        -> from stu, (
        -> select 'BANJI_ID' as LZ_TYPE, banji.id as ID,xuexiao.NAME
        -> from banji,nianji,xuexiao
        -> where banji.NIANJI_ID=nianji.ID
        -> and nianji.XUEXIAO_ID=xuexiao.ID
        -> union all
        -> select 'NIANJI_ID' as LZ_TYPE,nianji.id,xuexiao.NAME
        -> from nianji,xuexiao
        -> where nianji.XUEXIAO_ID=xuexiao.ID
        -> union all
        -> select 'XUEXIAO_ID' as LZ_TYPE,ID,xuexiao.NAME
        -> from xuexiao
        -> ) t
        -> where stu.LZ_TYPE=t.LZ_TYPE and LZ_ID=t.ID;
    +------+----------+----------+
    | ID   | NAME     | NAME     |
    +------+----------+----------+
    |    1 | 张学友   | 东门小学 |
    |    2 | 风清扬   | 东门小学 |
    |    2 | 刘德华   | 宝塔中学 |
    |    4 | 黎明     | 东门小学 |
    |    5 | 郭富城   | 宝塔中学 |
    |    6 | 迈克     | 宝塔中学 |
    |    7 | 天山童姥 | 东门小学 |
    |    8 | 李秋水   | 宝塔中学 |
    +------+----------+----------+
    8 rows in set (0.00 sec)mysql>
      

  13.   

    啊,对不起,风清扬的ID是错的,不过你谢谢你啊ACMAIN_CHM,你的语句可以。
    还如只有三种可能!
    wwwwb的太深奥了,我不明白,我是用PHP的。
    稍后结贴!
      

  14.   

    这是 动态SQL,
    SELECT  @ASQL1;
    看看内容
      

  15.   

    select s.name, xx.name from stu s inner join xuexiao xx on s.LZ_ID = xx.ID where s.LZ_TYPE = 'xuexiao_id'
    union all
    select s.name, xx.NAME from stu s 
    inner join nianji nj on s.LZ_ID = nj.id 
    inner join xuexiao xx on nj.xuexiao_id = xx.ID
    where s.LZ_TYPE = 'nianji_id'
    union all
    select s.NAME, xx.NAME from stu s 
    inner join banji bj on s.LZ_ID = bj.id
    inner join nianji nj on bj.nianji_id = nj.id
    inner join xuexiao xx on nj.xuexiao_id = xx.ID
    where s.LZ_TYPE = 'banji_id'