2013-08-03 227 views
1

我有以下數據庫結構。優化數據庫查詢

問題表。

id question    desc 
1 What was john's age? About john 

選項表

id question_id option_value correct_ans 
1  1    20    0 
2  1    18    0 
3  1    28    1 
4  1    60    0 

現在我想從兩個與他們的選擇所有問題的表格獲得備案。 我想要以下結構。我做了代碼並得到結果,但它花了兩個SQL查詢。首先從問題表中獲取所有問題,然後創建一個數組,然後獲取所有問題的選項並放入數組中。使用單個查詢有可能獲得這種類型的數據嗎?

 array([0]=array('question_id'=>1, 
         'question'=>'what was john's age', 
         'desc'=>'About john', 
         'options'=>array([0]=>array('option_id'=>'1', 
                'option_value'=>20, 
                'correct_ans'=>0), 
             [1]=>array('option_id'=>'2', 
                'option_value'=>18, 
                'correct_ans'=>0), 
             [2]=>array('option_id'=>'3', 
                'option_value'=>28, 
                'correct_ans'=>1), 
             [3]=>array('option_id'=>'4', 
                'option_value'=>60, 
                'correct_ans'=>0) 
             ) 
         ), 
      [1]=array('question_id'=>2, 
         etc............... 
+0

爲什麼你想要一個單一的查詢? 2個查詢是針對特定問題的完美解決方案。說「2個查詢比1個慢」實際上與「1 2美元優於2美元100美元」相同 – zerkms

回答

1

使用JOIN:

SELECT q.id question_id, question, desc, o.id option_id, option_value, correct_ans 
FROM question q 
LEFT JOIN option o 
ON q.id = o.question_id 
ORDER BY question_id, option_id 

這將使用LEFT JOIN所以你會得到關於就算沒有選項出現在options表(從options表中的列將問題信息在這種情況下爲NULL)。如果這不被允許,你可以使用INNER JOIN來代替。

此查詢的結果將重複每行的問題信息。從結果創建數組的循環將必須檢查question_id是否已從前一行更改。如果有,它會啓動頂層數組的一個新元素;如果question_id是相同的,則它將添加到當前數組元素的options元素。

+0

原始問題與「優化」有關。在這種情況下,使用'LEFT JOIN'解決方案几乎不會比2個查詢效率更高 – zerkms

+0

它真的只是2個查詢嗎?通常,連接的替代方法是執行一個查詢以獲取所有問題ID,然後按每個問題查詢以獲取所有選項。因此,如果有N個問題,那麼總共有N + 1個查詢。我知道你可以從第一個查詢中生成一個大的'WHERE question_id IN(...)'子句,但這不是人們通常所做的。無論如何,他問是否有辦法使用單個查詢來獲取所有內容,這就是它。 – Barmar

+0

「但這不是人們通常所做的事情」--- OP說他需要2次查詢。一旦這個問題被稱爲「優化」 - 我敢打賭,一個查詢的解決方案會消耗更多的資源(網絡+內存) – zerkms