-1

我有以下表格

  • 学生(sid,姓名,年龄)
  • 课程(cid,cname,持续时间)
  • 注册(sid,cid,日期)

查找学过java或rdbms的同学的sids

select sid 
from enroll e, 
     course c 
where (c.cname like 'java' and c.cid=e.cid) 
   or (c.cname like 'rdbms' and c.cid=e.cid);

或者:

select sid 
from enroll e, 
     course c 
where cname like 'java' and c.cid=e.cid
union 
select sid 
from enroll e, 
     course c 
where cname like 'rdbms' and c.cid=e.cid;

第二种选择:

select sid 
from enroll 
where cid in (select cid 
              from course 
              where cname like 'java' 
                 or cname like 'rdbms');

以上所有问题都让我得到了预期的结果。

为了找到学过 java和rdbms的学生的 sids ,我只是修改了所有 3,但下面的第 1 和第 3 个查询不起作用。

select sid 
from enroll e, 
     course c 
where (c.cname like 'java' and c.cid=e.cid) 
  and (c.cname like 'rdbms' and c.cid=e.cid);

选择:

select sid 
from enroll e, 
     course c 
where cname like 'java' and c.cid=e.cid
intersect 
select sid 
from enroll e, 
     course c 
where cname like 'rdbms' and c.cid=e.cid;

第二种选择:

select sid 
from enroll 
where cid in (select cid 
              from course 
              where cname like 'java' and cname like 'rdbms');
4

4 回答 4

1

编写 OR 查询的一种方法是:

SELECT DISTINCT sid
  FROM enroll e JOIN course c ON c.cid = e.cid
 WHERE c.cname IN ('java', 'rdbms');

编写 AND 查询的一种方法是:

SELECT DISTINCT sid
  FROM enroll e JOIN course c ON c.cid = e.cid
 WHERE c.cname IN ('java', 'rdbms')
 GROUP BY sid
HAVING COUNT(*) = 2;

这要求在所选学生的注册表中显示两行,每门课程一个(假设一个学生不能为一门课程注册两次)。如果可以,那么您需要类似COUNT(DISTINCT cid) = 2HAVING 子句中的内容。


分析您的非工作查询:

select sid 
from enroll e, 
     course c 
where (c.cname like 'java' and c.cid=e.cid) 
  and (c.cname like 'rdbms' and c.cid=e.cid);

这可以写得更清楚,也许是:

SELECT sid 
  FROM enroll e JOIN course c ON c.cid = e.cid
 WHERE (c.cname = 'java' AND c.cname = 'rdbms');

现在,如果课程名称是“java”,它显然不是“rdbms”,反之亦然,因此没有任何一行可以满足条件。您必须分析具有​​相同 sid 的两行。因此,此查询不够复杂,无法回答问题。

第二种选择:

select sid 
from enroll 
where cid in (select cid 
              from course 
              where cname like 'java' and cname like 'rdbms');

这遇到了同样的问题;Course 表中不能存在 cname 同时为“java”和“rdbms”的单行。

于 2012-10-05T06:31:47.113 回答
0

尝试这个

select sid 
from enroll e
where exists(select 0
              from course c
              where c.cname like 'java'
                and c.cid = e.cid)
  and exists(select 0
              from course c
              where c.cname like 'rdbms'
                and c.cid = e.cid)

祝你好运

于 2012-10-05T12:06:41.957 回答
0

第一个和第三个不起作用的原因是他们声明 cname 应该同时是“java”和“rdbms”!第三个查询可以这样重写:

select distinct sid 
  from enroll 
  where cid in (select cid 
                  from course 
                where cname like 'java' or cname like 'rdbms');

这应该为您提供参加过 java 或 rdbms 课程的学生的所有记录。

于 2012-10-05T13:23:35.643 回答
0

我建议您提供比“不工作”更多的信息。你应该描述你的期望和你得到的。

话虽如此,我可以建议一个查询来替换第一个查询,它可以让您获得同时使用 java 和 rdbms 的 sid:

select distinct sid 
from enroll e, course c 
where c.cid=e.cid
and c.cname in ('java','rdbms');

有许多不同的方法可以做到这一点,根据您的最终要求,可能会有更好的方法。毫无疑问,有人会提出一种“更好”的方法,但这实际上取决于最终要求。

您的最后一个查询不起作用,因为它的这一部分:

select cid from course where cname like 'java' and cname like 'rdbms'

是说给我一个课程记录,其中课程名称是 java,课程名称是 rdbms

当然,这样的记录永远不会存在。这就像说给我介绍一个叫 Fred 和 Bob 的人。

同样取决于 RDBMS,使用不带通配符的 like 也不会得到任何结果。

于 2012-10-05T06:19:36.220 回答