- 论坛徽章:
- 0
|
假设有下面的表和数据:
- use test;
- drop table if exists LeftJoinTest_QATemplate;
- create table LeftJoinTest_QATemplate (`考核项` varchar(20), `结果` enum('好','差'), `得分` int, primary key (`考核项`, `结果`)) comment '考核项模板';
- drop table if exists LeftJoinTest_QAResult;
- create table LeftJoinTest_QAResult (`姓名` varchar(10), `考核项` varchar(20), `结果` enum('好','差'), primary key (`姓名`, `考核项`)) comment '考核结果';
- insert into LeftJoinTest_QATemplate (`考核项`, `结果`, `得分`) values ('工作态度', '好', 10);
- insert into LeftJoinTest_QATemplate (`考核项`, `结果`, `得分`) values ('工作态度', '差', -10);
- insert into LeftJoinTest_QATemplate (`考核项`, `结果`, `得分`) values ('工作效率', '好', 20);
- insert into LeftJoinTest_QATemplate (`考核项`, `结果`, `得分`) values ('工作效率', '差', -20);
- insert into LeftJoinTest_QATemplate (`考核项`, `结果`, `得分`) values ('工作能力', '好', 30);
- insert into LeftJoinTest_QATemplate (`考核项`, `结果`, `得分`) values ('工作能力', '差', -30);
- insert into LeftJoinTest_QAResult (`姓名`, `考核项`, `结果`) values ('赵', '工作态度', '差');
- --insert into LeftJoinTest_QAResult (`姓名`, `考核项`, `结果`) values ('赵', '工作效率', null);
- --insert into LeftJoinTest_QAResult (`姓名`, `考核项`, `结果`) values ('赵', '工作能力', null);
- insert into LeftJoinTest_QAResult (`姓名`, `考核项`, `结果`) values ('钱', '工作态度', '差');
- --insert into LeftJoinTest_QAResult (`姓名`, `考核项`, `结果`) values ('钱', '工作效率', null);
- insert into LeftJoinTest_QAResult (`姓名`, `考核项`, `结果`) values ('钱', '工作能力', '好');
- --insert into LeftJoinTest_QAResult (`姓名`, `考核项`, `结果`) values ('钱', '工作态度', null);
- insert into LeftJoinTest_QAResult (`姓名`, `考核项`, `结果`) values ('孙', '工作效率', '差');
- --insert into LeftJoinTest_QAResult (`姓名`, `考核项`, `结果`) values ('钱', '工作能力', null);
复制代码
现在想查出每个人、每个/所有考核项的结果(如果 LeftJoinTest_QAResult 表中不存在某人的某个考核项,则该某人的该考核项的结果必须为 NULL,而不能不存在这条记录 )
--得到预期结果如下:
- /*
- +------+----------+------+
- | 姓名 | 考核项 | 结果 |
- +------+----------+------+
- | 赵 | 工作态度 | 差 |
- | 赵 | 工作效率 | NULL |
- | 赵 | 工作能力 | NULL |
- | 钱 | 工作态度 | 差 |
- | 钱 | 工作效率 | NULL |
- | 钱 | 工作能力 | 好 |
- | 孙 | 工作态度 | NULL |
- | 孙 | 工作效率 | 差 |
- | 孙 | 工作能力 | NULL |
- +------+----------+------+
- */
- --SQL:
- select '赵' 姓名,t.考核项,r1.结果
- from
- (select distinct 考核项 from LeftJoinTest_QATemplate) t
- left join
- (select * from LeftJoinTest_QAResult where 姓名='赵') r1 on t.考核项=r1.考核项
- union
- select '钱',t.考核项,r2.结果
- from
- (select distinct 考核项 from LeftJoinTest_QATemplate) t
- left join
- (select * from LeftJoinTest_QAResult where 姓名='钱') r2 on t.考核项=r2.考核项
- union
- select '孙',t.考核项,r3.结果
- from
- (select distinct 考核项 from LeftJoinTest_QATemplate) t
- left join
- (select * from LeftJoinTest_QAResult where 姓名='孙') r3 on t.考核项=r3.考核项
- ;
复制代码
问题:由于 LeftJoinTest_QAResult 表中的“姓名”具有不确定性,所以上面根据固定姓名写出的 SQL 语句无法在实际中应用,所以希望能有一个通用的 SQL 语句来得到预期结果,但不知道如何实现。
另外:
如果在 LeftJoinTest_QAResult 表中把每个人缺少的考核项补充进去,然后用一个简单的 SELECT 语句查询出来,也能得到预期的结果,但这不是我希望的,因为
1、实际应用中,考核项很多,而需要保存的考核项很少,这种方法就导致大量无用的数据存放在数据库中
2、实际应用中,考核项是会变更的(考核模板变更),当加入了新的考核项后,依然是会出现考核项结果缺少的情况
- /*
- -- 补充行
- insert into LeftJoinTest_QAResult (`姓名`, `考核项`, `结果`) values ('赵', '工作效率', null);
- insert into LeftJoinTest_QAResult (`姓名`, `考核项`, `结果`) values ('赵', '工作能力', null);
- insert into LeftJoinTest_QAResult (`姓名`, `考核项`, `结果`) values ('钱', '工作效率', null);
- insert into LeftJoinTest_QAResult (`姓名`, `考核项`, `结果`) values ('钱', '工作态度', null);
- insert into LeftJoinTest_QAResult (`姓名`, `考核项`, `结果`) values ('钱', '工作能力', null);
- -- 预期结果:
- select * from LeftJoinTest_QAResult order by 姓名;
- */
复制代码
[ 本帖最后由 lovetide 于 2009-7-2 23:54 编辑 ] |
|