请教一条SQL语句

时间:2021-11-29 11:43:30
表M:nsid,xm,xb,school 
表a:nsid,Ksdc--Ksdc为考试等次,仅合格与不合格,记载科目a成绩 
表b:nsid,Ksdc--Ksdc为考试等次,仅合格与不合格,记载科目b成绩 
表C:nsid,Ksdc--Ksdc为考试等次,仅合格与不合格,记载科目c成绩 
  一个nsid在a、b、c中可能有多条记录,也可能没有记录,但只有一条“合格”记录。 

查询: 
  xm,nsid,xb,school,a.ksdc,b.ksdc,c.ksdc 
要求: 
每个学员一条记录; 
如果该学员某科目中有合格记录,则显示合格;如果有记录但没有合格记录,则显示不合格;如果没有任何记录,则显示为空 

以下代码得不到正确结果 
select distinct m.xm,m.xb,m.nsid,m.school, 
a.ksdc,b.ksdc,c.ksdc from tbjbxx m 
left  join tbkone a on m.nsid=a.nsid 
left join  tbktwo b on m.nsid=b.nsid 
left join  tbkthree c on m.nsid=c.nsid

原因是 distinct 把符合条件的记录给剔除了。

7 个解决方案

#1



create table m (nsid number, xm varchar2(20), xb char(1), school varchar2(20));

create table a (nsid number, ksdc char(1));
create table b (nsid number, ksdc char(1));
create table c (nsid number, ksdc char(1));

insert into m values (1, 'Andy', 'M', 'S1');
insert into m values (2, 'Baby', 'F', 'S2');

insert into a values (1, 'N');
insert into a values (1, 'N');
insert into a values (1, 'Y');
insert into a values (2, 'N');

insert into b values (1, 'N');
insert into b values (1, 'N');


insert into c values (1, 'N');
insert into c values (1, 'N');
insert into c values (2, 'Y');

commit;

select g.nsid, g.xm, g.xb, g.school, 
       decode(g.ca, 0, null, decode(yca, 0, 'Not passed', 'Passed')) sa,
       decode(g.cb, 0, null, decode(ycb, 0, 'Not passed', 'Passed')) sb,
       decode(g.cc, 0, null, decode(ycc, 0, 'Not passed', 'Passed')) sc
from  
(
select M.NSID, m.xm, m.xb, M.SCHOOL,
       (select count(nsid) from a where a.nsid=m.nsid) ca ,
       (select count(nsid) from b where b.nsid=m.nsid) cb ,
       (select count(nsid) from c where c.nsid=m.nsid) cc ,
       (select count(nsid) from a where a.nsid=m.nsid and a.ksdc = 'Y') yca ,
       (select count(nsid) from b where b.nsid=m.nsid and b.ksdc = 'Y') ycb ,
       (select count(nsid) from c where c.nsid=m.nsid and c.ksdc = 'Y') ycc 
from m
) g

      NSID XM         XB SCHOOL     SA              SB              SC             
---------- ---------- -- ---------- --------------- --------------- ---------------
         1 Andy       M  S1         Passed          Not passed      Not passed     
         2 Baby       F  S2         Not passed                      Passed         

#2


建议楼主发个测试数据。。。

#3


谢谢nGX20080110,比想像的要复杂,让我试试。

#4


不过sql anywhere中只有case when end,没有decode,我还得改一改

#5


create table m (nsid number, xm varchar2(20), xb char(1), school varchar2(20));

create table a (nsid number, ksdc char(1));
create table b (nsid number, ksdc char(1));
create table c (nsid number, ksdc char(1));

insert into m values (1, 'Andy', 'M', 'S1');
insert into m values (2, 'Baby', 'F', 'S2');

insert into a values (1, 'N');
insert into a values (1, 'N');
insert into a values (1, 'Y');
insert into a values (2, 'N');

insert into b values (1, 'N');
insert into b values (1, 'N');


insert into c values (1, 'N');
insert into c values (1, 'N');
insert into c values (2, 'Y');

commit;


select M.NSID, m.xm, m.xb, M.SCHOOL,
  case when a.g1>0 then '合格'
       when a.g2>0 then '不合格'
       else null 
  end  ksdcA,   --a科目成绩
  case when b.g1>0 then '合格'
       when b.g2>0 then '不合格'
       else null 
  end  ksdcb,   --b科目成绩
  case when c.g1>0 then '合格'
       when c.g2>0 then '不合格'
       else null 
  end  ksdcc   --c科目成绩
from m left join 
(select nsid,
    count(case when ksdc = 'Y' then 1 else null end) g1,  --合格次数
    count(case when ksdc = 'N' then 1 else null end) g2   --不合格次数
  from a
  group by nsid 
 ) a on m.nsid = a.nsid
 left join
 (select nsid,
    count(case when ksdc = 'Y' then 1 else null end) g1,  --合格次数
    count(case when ksdc = 'N' then 1 else null end) g2   --不合格次数
  from b
  group by nsid 
 ) b on m.nsid = b.nsid
 left join 
 (select nsid,
    count(case when ksdc = 'Y' then 1 else null end) g1,  --合格次数
    count(case when ksdc = 'N' then 1 else null end) g2   --不合格次数
  from c
  group by nsid 
 ) c on m.nsid = c.nsid

#6


表中有重复数据!                     .

#7


47522341(睡到8:30) 的结果完全正确,选择的记录完全符合要求
原来子查询中定义的变量还可以反过来在主查询中使用,好多教科书上都没有这样教过。
感谢47522341(睡到8:30),您是一名真正的数据库高手。
感谢nGX20080110大师,虽然我不懂oracle语法,但您的结果看得出来也是正确的。
别请两位大师到同样问题的一个帖子
http://topic.csdn.net/u/20100309/14/5337a19e-c0f3-4feb-b50c-771aeb48f9d5.html?seed=935278040&r=63805408#r_63805408
做下解答,该贴的分一并给两位大师
感谢csdn

#1



create table m (nsid number, xm varchar2(20), xb char(1), school varchar2(20));

create table a (nsid number, ksdc char(1));
create table b (nsid number, ksdc char(1));
create table c (nsid number, ksdc char(1));

insert into m values (1, 'Andy', 'M', 'S1');
insert into m values (2, 'Baby', 'F', 'S2');

insert into a values (1, 'N');
insert into a values (1, 'N');
insert into a values (1, 'Y');
insert into a values (2, 'N');

insert into b values (1, 'N');
insert into b values (1, 'N');


insert into c values (1, 'N');
insert into c values (1, 'N');
insert into c values (2, 'Y');

commit;

select g.nsid, g.xm, g.xb, g.school, 
       decode(g.ca, 0, null, decode(yca, 0, 'Not passed', 'Passed')) sa,
       decode(g.cb, 0, null, decode(ycb, 0, 'Not passed', 'Passed')) sb,
       decode(g.cc, 0, null, decode(ycc, 0, 'Not passed', 'Passed')) sc
from  
(
select M.NSID, m.xm, m.xb, M.SCHOOL,
       (select count(nsid) from a where a.nsid=m.nsid) ca ,
       (select count(nsid) from b where b.nsid=m.nsid) cb ,
       (select count(nsid) from c where c.nsid=m.nsid) cc ,
       (select count(nsid) from a where a.nsid=m.nsid and a.ksdc = 'Y') yca ,
       (select count(nsid) from b where b.nsid=m.nsid and b.ksdc = 'Y') ycb ,
       (select count(nsid) from c where c.nsid=m.nsid and c.ksdc = 'Y') ycc 
from m
) g

      NSID XM         XB SCHOOL     SA              SB              SC             
---------- ---------- -- ---------- --------------- --------------- ---------------
         1 Andy       M  S1         Passed          Not passed      Not passed     
         2 Baby       F  S2         Not passed                      Passed         

#2


建议楼主发个测试数据。。。

#3


谢谢nGX20080110,比想像的要复杂,让我试试。

#4


不过sql anywhere中只有case when end,没有decode,我还得改一改

#5


create table m (nsid number, xm varchar2(20), xb char(1), school varchar2(20));

create table a (nsid number, ksdc char(1));
create table b (nsid number, ksdc char(1));
create table c (nsid number, ksdc char(1));

insert into m values (1, 'Andy', 'M', 'S1');
insert into m values (2, 'Baby', 'F', 'S2');

insert into a values (1, 'N');
insert into a values (1, 'N');
insert into a values (1, 'Y');
insert into a values (2, 'N');

insert into b values (1, 'N');
insert into b values (1, 'N');


insert into c values (1, 'N');
insert into c values (1, 'N');
insert into c values (2, 'Y');

commit;


select M.NSID, m.xm, m.xb, M.SCHOOL,
  case when a.g1>0 then '合格'
       when a.g2>0 then '不合格'
       else null 
  end  ksdcA,   --a科目成绩
  case when b.g1>0 then '合格'
       when b.g2>0 then '不合格'
       else null 
  end  ksdcb,   --b科目成绩
  case when c.g1>0 then '合格'
       when c.g2>0 then '不合格'
       else null 
  end  ksdcc   --c科目成绩
from m left join 
(select nsid,
    count(case when ksdc = 'Y' then 1 else null end) g1,  --合格次数
    count(case when ksdc = 'N' then 1 else null end) g2   --不合格次数
  from a
  group by nsid 
 ) a on m.nsid = a.nsid
 left join
 (select nsid,
    count(case when ksdc = 'Y' then 1 else null end) g1,  --合格次数
    count(case when ksdc = 'N' then 1 else null end) g2   --不合格次数
  from b
  group by nsid 
 ) b on m.nsid = b.nsid
 left join 
 (select nsid,
    count(case when ksdc = 'Y' then 1 else null end) g1,  --合格次数
    count(case when ksdc = 'N' then 1 else null end) g2   --不合格次数
  from c
  group by nsid 
 ) c on m.nsid = c.nsid

#6


表中有重复数据!                     .

#7


47522341(睡到8:30) 的结果完全正确,选择的记录完全符合要求
原来子查询中定义的变量还可以反过来在主查询中使用,好多教科书上都没有这样教过。
感谢47522341(睡到8:30),您是一名真正的数据库高手。
感谢nGX20080110大师,虽然我不懂oracle语法,但您的结果看得出来也是正确的。
别请两位大师到同样问题的一个帖子
http://topic.csdn.net/u/20100309/14/5337a19e-c0f3-4feb-b50c-771aeb48f9d5.html?seed=935278040&r=63805408#r_63805408
做下解答,该贴的分一并给两位大师
感谢csdn