[英]Most common values for a group dependent on a select query
我對如何在SQL中執行此操作感到不滿。 我有一張桌子:
| User_id | Question_ID | Answer_ID |
| 1 | 1 | 1 |
| 1 | 2 | 10 |
| 2 | 1 | 2 |
| 2 | 2 | 11 |
| 3 | 1 | 1 |
| 3 | 2 | 10 |
| 4 | 1 | 1 |
| 4 | 2 | 10 |
它保存用戶對特定問題的答案。 一個問題可能有多個答案。 用戶無法回答兩次相同的問題。 (因此,每{User_id,Question_ID}只有一個Answer_ID)
我正在嘗試找到這個查詢的答案:對於特定的問題和答案ID(與同一問題相關),我想找到給定答案的用戶給出的其他問題的最常見答案。
例如,對於上表:
For question_id = 1 -> For Answer_ID = 1 - (Question 2 - Answer ID 10)
For Answer_ID = 2 - (Question 2 - Answer ID 11)
是否可以在一個查詢中執行? 它應該在一個查詢中完成嗎? 我應該只使用存儲過程或Java嗎?
你想要一條魚嗎? 或者你想學習如何釣魚?
您的問題似乎有多個步驟。
獲取有關“具有給定答案的用戶的問題”的信息。 設計這個SELECT
並想象結果形成一個新表。
應用“OTHER”限制。 這可能是一個小的AND ... != ...
添加到SELECT #1
。
現在找到“最常見的答案”。 這可能涉及ORDER BY COUNT(*) DESC LIMIT 1
。 很可能
使用派生表:
SELECT ...
FROM ( select#2 )
雖然@ rick-james是對的,但我不確定如果不是這樣的查詢通常是針對MySQL編寫的,那么很容易啟動。
您需要查詢才能找到問題的最常見答案:
SELECT question_id, answer_id, COUNT(*) as cnt FROM user_answers GROUP BY 1, 2 ORDER BY 1, 3 DESC
這將返回一個表,其中我們輸出的每個question_id按降序排列。
| 1 | 1 | 3 | | 1 | 2 | 1 | | 2 | 10 | 3 | | 2 | 11 | 1 |
現在我們應該解決一個所謂的最大n組的任務。 問題在於,在MySQL中為了性能,這樣的任務通常不是在純SQL中解決,而是使用黑客來解決如何在內部處理查詢的知識。
在這種情況下,我們知道我們可以定義一個變量然后迭代就緒表,了解前一行,這允許我們區分組中的第一行和其他行。
SELECT question_id, answer_id, cnt, IF(question_id=@q_id, NULL, @q_id:=question_id) as v FROM ( SELECT question_id, answer_id, COUNT(*) as cnt FROM user_answers GROUP BY 1, 2 ORDER BY 1, 3 DESC) cnts JOIN ( SELECT @q_id:=-1 ) as init;
確保已初始化變量(並在初始化時尊重其數據類型,否則可能會在以后意外地進行轉換)。 結果如下:
| 1 | 1 | 3 | 1 | | 1 | 2 | 1 |(null)| | 2 | 10 | 3 | 2 | | 2 | 11 | 1 |(null)|
現在我們只需要在最后一列中過濾出NULL的行。 由於實際上不需要該列,我們可以將相同的表達式移動到WHERE子句中。 實際上也不需要cnt列,所以我們也可以跳過它:
SELECT question_id, answer_id FROM ( SELECT question_id, answer_id FROM user_answers GROUP BY 1, 2 ORDER BY 1, COUNT(*) DESC) cnts JOIN ( SELECT @q_id:=-1 ) as init WHERE IF(question_id=@q_id, NULL, @q_id:=question_id) IS NOT NULL;
最后一件值得一提的是,為了使查詢有效,你應該有正確的索引。 此查詢需要以(question_id,answer_id)列開頭的索引。 由於您無論如何都需要UNIQUE索引,因此按以下順序定義它是有意義的:(question_id,answer_id,user_id)。
CREATE TABLE user_answers ( user_id INTEGER, question_id INTEGER, answer_id INTEGER, UNIQUE INDEX (question_id, answer_id, user_id) ) engine=InnoDB;
這是一個可以使用的sqlfiddle: http ://sqlfiddle.com/#!9 / bd12ad / 20。
您的問題是多條件的,您必須在Question
表中向他們的詢問用戶提出第一個問題:
select question_id,user_id from question
然后插入問題的答案,並在您的Java代碼中進行一些檢查(用戶已經回答了與提出此問題的用戶相同的問題,用戶多次回答此問題)。
select question_id,user_id from question where user_id=asking-user_id // gets all questions and show on UI
select answer_id,user_id from answer where user_id=answering-user_id // checks the answers that particular user
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.