2009-05-27 26 views
2

我需要拿出一個SQL查詢返回滿足多個條件行。本文介紹我需要做的和解決方案: 組完整的SQL

基本上它使用了一點操作來找出是否找到提供的字符串..但我很難跟蹤它的工作原理。

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 | 
+-------------+ 

我測試了它,它按預期工作。有人可以解釋這是如何工作的?

感謝, 阿米

+0

我建議你複製和粘貼代碼片段你指的是,關閉該網站的特定代碼,粘貼到你的問題,和短語爲「誰能解釋這是如何工作」 – 2009-05-27 19:56:56

+0

沒問題..謝謝這個建議。 – Grnbeagle 2009-05-27 20:11:53

回答

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(...),在默認情況下會是答案的數目來檢查了一套完整的價值。

1

如果有匹配列表中的一個值,一個位設置和左移多次匹配項的列表中的位置。 group-by對每個學生的所有單個位圖執行xor操作,生成一個包含相同信息的單個值(爲每個匹配值設置一個位)。

這種方法顯然是由返回類型可容納的比特的數量的限制。

+0

我想我對整個位操作感到困惑。感謝您的輸入! – Grnbeagle 2009-05-27 23:11:25

0

The MySQL documentation解釋FIND_IN_SET()「返回(S)的第二個參數中的第一個參數的索引位置」。鑑於該組可用的問題是「A」,「B」或「C」,我們可以利用這個查詢,看看有什麼FIND_IN_SET()做:

SELECT studentName, 
     question, 
     FIND_IN_SET(question, 'A,B,C') AS position 
FROM quizAnswers; 

使用他們爲榜樣的記錄,我們將得到:

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

他們現在建議你把它變成一個位掩碼和使用按位異或,以消除任何給定的(studentName,問題)對重複。