簡體   English   中英

組的最常見值取決於選擇查詢

[英]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嗎?

你想要一條魚嗎? 或者你想學習如何釣魚?

您的問題似乎有多個步驟。

  1. 獲取有關“具有給定答案的用戶的問題”的信息。 設計這個SELECT並想象結果形成一個新表。

  2. 應用“OTHER”限制。 這可能是一個小的AND ... != ...添加到SELECT #1

  3. 現在找到“最常見的答案”。 這可能涉及ORDER BY COUNT(*) DESC LIMIT 1 很可能

使用派生表:

SELECT ...
    FROM ( select#2 )

雖然@ rick-james是對的,但我不確定如果不是這樣的查詢通常是針對MySQL編寫的,那么很容易啟動。

  1. 您需要查詢才能找到問題的最常見答案:

     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 | 
  2. 現在我們應該解決一個所謂的最大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)| 
  3. 現在我們只需要在最后一列中過濾出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; 
  4. 最后一件值得一提的是,為了使查詢有效,你應該有正確的索引。 此查詢需要以(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM