2013-08-03 175 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