1

この質問を組み立てる方法がわからないので、SQL ステートメントをここに直接入れます。

declare @tbl table(Id varchar(4),Userid varchar(10),Name varchar(max),Course varchar(max))
insert into @tbl values
('1','UserID1','UserA','Physics'),
('2','UserID2','UserB','Chemistry'),
('3,','UserID1','UserA','Chemistry')

今、

Chemistry を受講したユーザーのリストを取得するには、次のように記述します。

select * from @tbl where Course='Chemistry'

物理学についても同様に、私は書きます

select * from @tbl where Course='Physics'

問題は、「物理学を受講していない学生のリストを取得する」というクエリを作成しようとしたときです。あまり考えずに書いてみた

select * from @tbl where Course!='Physics'

結果は間違っています(UserAに関する詳細を取得しています-彼は物理学に登録していますが)

Id  Userid  Name    Course
2   UserID2 UserB   Chemistry
3,  UserID1 UserA   Chemistry

これを修正するために、クエリを次のように書き直しましたが、どういうわけかこれは正しい方法ではないと思います。

select * from @tbl where Course!='Physics'
and Userid not in (select Userid from @tbl where Course='Physics')

助けてください!

4

2 に答える 2

1

物理学を受講していない学生のリストが必要な場合は、having 句を使用して集計することをお勧めします。

select userId
from @tbl
group by userId
having sum(case when course = 'Physics' then 1 else 0 end) = 0;

これには、学生 ID のみを返すという明らかな利点があり、1 人の学生に対して複数の行を返すことはありません (他に複数のコースがある場合)。whereこれは「set-within-sets」サブクエリの例でもあり、バージョンよりも簡単に一般化できます。マイナス面としては、 を使用するとnot exists、インデックスをより有効に活用できる場合があります。

于 2013-10-17T22:47:11.613 に答える
1

次のことを試してください。

SELECT *
       FROM @tlb U
       WHERE NOT EXISTS (SELECT  *
                                 FROM @tbl Inner
                                 WHERE Inner.UserId = U.UserId
                                 AND Course = 'Physics')

NOT INvsの詳細については、この質問EXISTSを参照してください。コンセンサスは、それが好ましいようです。NOT EXISTS

(テーブル定義では列が としてマークされていないことに注意してくださいNOT NULL。シナリオにそれを追加することが適切である場合は、それをお勧めします。)

于 2013-10-17T22:13:12.707 に答える