-1

次のテーブルがあります

  • 生徒(シド、スネーム、年齢)
  • コース(cid、cname、期間)
  • 登録 (sid、cid、日付)

javaまたはrdbmsを受講した学生の sid を見つける

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;

2 番目の選択肢:

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

上記のクエリはすべて、期待どおりの結果をもたらします。

javaとrdbmsを受講した学生の sid を見つけるために、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;

2 番目の選択肢:

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

4 に答える 4

1

OR クエリを記述する 1 つの方法は次のとおりです。

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

AND クエリを記述する 1 つの方法は次のとおりです。

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;

これには、選択した学生の登録テーブルに、各コースに 1 つずつ、2 つの行が表示される必要があります (学生が 1 つのコースに 2 回登録できないことを前提としています)。COUNT(DISTINCT cid) = 2可能であれば、HAVING 句のようなものが必要です。


機能しないクエリの分析:

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 を持つ 2 つの行を分析する必要があります。したがって、このクエリは質問に答えるほど複雑ではありません。

2 番目の選択肢:

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

これは同じ問題に遭遇します。cname が同時に 'java' と 'rdbms' である Course テーブルに単一の行を含めることはできません。

于 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

1 番目と 3 番目が機能しない理由は、cname が同時に 'java' と 'rdbms' の両方であるべきだと述べているからです! 3 番目のクエリは次のように書き直すことができます。

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 のコース レコードを取得してくださいと言っています

もちろん、そのような記録は存在しません。それは、フレッドとボブという名前の人を紹介してくれと言っているようなものです。

また、RDBMS によっては、ワイルドカード文字なしで like を使用しても結果が得られません。

于 2012-10-05T06:19:36.220 に答える