3

以下に示すように、いくつかのフィールドとサンプル レコードを含むデータベース テーブルがあります。

Name    Test    Result  Other_fields  
A      English    P         x  
B      Maths      F         x  
C      English    P         x  
B      English    P         x  
A      Maths      F         x  
D      English    P         x  
C      Biology    F         x  
A      Biology    P         x  
B      Biology    F         x  

現在、実際のテーブルには、より多くのさまざまなテストが含まれています。
私が達成したいのは、カンマ区切りの文字列で指定されたすべてのテストに合格した学生の数/リスト(および学生に固有の他のフィールドの対応する値...年齢、性別など)を見つけることです. 文字列は明らかに実行時にクエリに挿入されます。

これで、2 つのテストまたは 3 つのテストなどの固定数のテストである場合、そのクエリを作成できます。
しかし、実際の問題は、CSV 文字列内のテストの数が修正されていないことです。
これを達成する方法はありますか?

PS: SQL IN の使用を含む回答を提案する予定がある場合は、テスト名を一意の番号 (テスト ID として機能するため) に置き換えてもかまいません。

編集

どうやら、私は自分自身をはっきりさせていませんでした。テーブルには、多数のテスト (test1、test2、....test100 など) のレコードが含まれます。CSV 文字列には、これらのテストのいくつかが含まれます (たとえば、2 つ、3 つ、または 4 つですが、1 つ以上であることは間違いありません)。そして、学生がCSV文字列で指定されたすべてのテストに合格したデータが必要です。

EDIT 2
学生とテストの1つの組み合わせに対応する複数のレコードが存在する可能性があります(複数回の合格と不合格)

4

2 に答える 2

4
SELECT DISTINCT Name 
  FROM Table t
 WHERE NOT EXISTS(SELECT 1
                    FROM Table 
                   WHERE     t.Name = Name 
                         AND Result = 'F'
                         AND ',' || CsvOfTests || ',' LIKE '%,' || Test || ',%'
                 )

ここでは、名前の代わりに自動インクリメント ID などの一意の値を使用することをお勧めします。結果セットに追加のフィールドが必要な場合は、それらを SELECT および GROUP BY フィールド リストに含めるか、結合を使用して含めることができます。

CsvOfTests は、関心のあるテストのリストです。あるテストの名前が他のテストの名前の部分文字列である場合に備えて、CsvOfTests と Test の最初と最後にコンマを追加しました。ただし、テストをcsv文字列ではなく一時テーブルに配置すると、クエリがはるかに単純になり、ハッキリしなくなると思います。

入力文字列がコンマ以上でテストを区切る場合 (コンマの後のスペースのように、それらも含める必要があります)。それよりも複雑な場合は、 REGEXP_LIKE を試すか、独自の関数を作成すると思います。

リクエストごとに、渡されたサブジェクトをカウントするクエリ

SELECT DISTINCT Name 
  FROM Table t
 WHERE LENGTH(CsvOfTests) - LENGTH(REPLACE(CsvOfTests, ',')) + 1 = (
                  SELECT COUNT(1)
                    FROM Table 
                   WHERE     t.Name = Name 
                         AND Result = 'P'
                         AND ',' || CsvOfTests || ',' LIKE '%,' || Test || ',%'
                 )

ここでLENGTH(CsvOfTests) - LENGTH(REPLACE(CsvOfTests, ',')) + 1は、リスト内のテストの数をカウントします。次に、学生が合格したテストの数を数えます。明らかに、11g リリース 1 で同じことを行うREGEXP_COUNTもあります。

あなたの質問を読み直して考えたところ、これはまさにあなたが求めていたものではないことがわかりました. このクエリの目的は、学生が各科目に合格したかどうかを確認することです (つまり、最初に試験に失敗した場合は、再受験して最終的に合格します)。

于 2013-10-29T06:19:10.070 に答える