2009-05-27 2 views
2

複数の条件を満たす行を返すSQLクエリを用意する必要がありました。この記事では、私がしなければならなかったことと解決策について説明します: http://thenoyes.com/littlenoise/?p=58SQLで完全セット

基本的には、ビット操作を使用して、指定された文字列が見つかったかどうかを確認します。

SET @q = 'A,B'; 

SELECT studentName 
FROM quizAnswers 
GROUP BY studentName 
HAVING 
     BIT_OR(1 << FIND_IN_SET(question, @q) - 1) 
    = 
     (1 << LENGTH(@q) - LENGTH(REPLACE(@q, ',', '')) + 1) - 1; -- This is 2^numValues - 1 
+-------------+ 
| studentName | 
+-------------+ 
| seekwill | 
+-------------+ 

私はそれをテストし、期待どおりに動作します。誰かがこの仕組みを説明することはできますか?

おかげで、

Amieの
+0

私はあなたが参照している特定のコードスニペットをコピーして貼り付けて、そのサイトから貼り付けて、質問に貼り付けて「誰かがこの作品の仕組みを説明できるか」と尋ねます。 –

+0

確かに..ありがとう提案。 – Grnbeagle

答えて

2

私はBIT_ORが何をしているのか説明しません。

代替ソリューション:

ことが可能であるならば、私は通常、ベンダー固有の機能に依存しない純粋 SQLソリューションを好みます。何が必要なのあなたはを参照してください記事の例に類似している場合、このSQL文は任意のRDBMSにほとんどを実行し、目的の結果を生成する必要があります

-- //return those students that have correctly answered not less then 3 questions among A,B,C 
select  studentName, COUNT(DISTINCT question) AS CNT 
from  quizAnswers 
where  question in ('A', 'B', 'C') 
GROUP BY studentName 
HAVING COUNT(DISTINCT question) >= 3 

をしてHAVING COUNT...で遊んであなたも、より柔軟です:

-- //return those students that have correctly answered at least 1 question among A,B (either A or B) 
select  studentName, COUNT(DISTINCT question) AS CNT 
from  quizAnswers 
where  question in ('A', 'B',) 
GROUP BY studentName 
HAVING COUNT(DISTINCT question) >= 1 

は、基本的にはあなただけの一部where question in (...)...を記入し、デフォルトでは回答数がコンプリートセットをチェックすることですCOUNT(...)、の値を設定する必要があります。

+0

ありがとうございました!私はこの方法を試してみて、それは美しく働いています。そして、それは隠されていません。 :) – Grnbeagle

+0

と私には元のクエリを説明:) –

1

リスト内のいずれかの値に一致がある場合には、ビットが設定され、リスト内の一致する項目の位置何度でもを左にシフト。 group-byは、学生1人あたりの個々のビットマップすべてに対してxor演算を行い、同じ情報(存在する一致する値ごとに1ビットが設定されます)を含む単一の値になります。

このメソッドは、戻り値の型が保持できるビット数によって明らかに制限されます。

+0

私はビット操作全体と混同していると思います。入力いただきありがとうございます! – Grnbeagle

0

The MySQL documentationは、FIND_IN_SET()が「第2引数内の第1引数のインデックス位置を返す」と説明しています。

その例レコードを使用して
SELECT studentName, 
     question, 
     FIND_IN_SET(question, 'A,B,C') AS position 
FROM quizAnswers; 

を、我々はよ:使用可能な一連の質問は、「A」、「B」、または「C」だったことを考えると、我々はFIND_IN_SET()がやっていることを確認するには、このクエリを使用することができます取得:

+-------------+----------+----------+ 
| studentName | question | position | 
+-------------+----------+----------+ 
| seekwill | A  |  1 | 
| seekwill | B  |  2 | 
| seekwill | C  |  3 | 
| roxlu  | A  |  1 | 
| fury  | B  |  2 | 
| fury  | B  |  2 | 
+-------------+----------+----------+ 

彼らは今、あなたはビットマスクにこれをオンにし、任意の(studentName、質問)ペアの重複を排除するために、ビット単位のXORを使用して示唆しています。

関連する問題