请教一个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不知道我表达清楚没有,希望高手指点。
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不知道我表达清楚没有,希望高手指点。
建议你列出你的表结构,并提供测试数据以及基于这些测试数据的所对应正确结果。
参考一下这个贴子的提问方式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)
这样想帮你的人可以直接搭建和你相同的环境,并在给出方案前进行测试,避免文字描述理解上的误差。
应该是这样的:ID,XUEXIAO_ID,NIANJI_ID,BANJI_ID,NAME
其实就是四个表:
一个是班级表,有一个字段对应年级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 李秋水 宝塔中学
*/
-> 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>
示例,自行修改
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 ;
(
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 李秋水 宝塔中学
*/这样应该不会有岐义了吧!
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()
-> 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>
还如只有三种可能!
wwwwb的太深奥了,我不明白,我是用PHP的。
稍后结贴!
SELECT @ASQL1;
看看内容
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'