使用Zend Framework 2中的多个SubSelect生成查询

时间:2013-12-03 09:17:16

标签: mysql zend-framework2 subquery

我一直在与Zend Framework 2争论一个问题。

此功能可创建过滤结果所需的子选择。

public function getResponsesByFilterArray($filter_array)
{
    $filter_array_count = 0;
    $limit = 100;
    $rowset = $this->tableGateway->select(
            function (\Zend\Db\Sql\Select $select) use($limit, $filter_array)
            {
                foreach($filter_array as $filter_model)
                {
                    $filter_array_count++;

                    $subselect = new \Zend\Db\Sql\Select();
                    $subselect->from('question_responses');
                    $subselect->where(array('question_id' => $filter_model->question_id));

                    switch($filter_model->comparison){
                        case $filter_model::$EQUALS:
                            $subselect->where->equalTo('float_value', (float) $filter_model->float_value);
                            break;
                        case $filter_model::$GREATER_THAN:
                            $subselect->where->greaterThan('float_value', (float) $filter_model->float_value);
                            break;
                        case $filter_model::$LESS_THAN:
                            $subselect->where->lessThan('float_value', (float) $filter_model->float_value);
                            break;
                    }

                    $select->join(array(
                        'subselect'.$filter_array_count =>$subselect), 
                        'survey_responses.id = subselect'.$filter_array_count.'.response_id', 
                        array('float_value'));

                }
                $select->group('id');
                //$select->limit($limit);

                $adapterPlatform = new \Zend\Db\Adapter\Platform\Mysql();
                echo $select->getSqlString($adapterPlatform);
            });

    return $rowset;
}

这相当于:

       $subselect = new \Zend\Db\Sql\Select();
                $subselect->from('question_responses');
                $subselect->where(array('question_id' => $filter_model->question_id));
                $subselect->where->lessThan('float_value', 2000);
                $select->join(array(
                    'subselect1' =>$subselect),
                        'survey_responses.id = subselect1.response_id',
                        array('float_value'));


                $subselect2 = new \Zend\Db\Sql\Select();
                $subselect2->from('question_responses');
                $subselect2->where(array('question_id' => $filter_model->question_id));
                $subselect2->where->greaterThan('float_value', 10);
                $select->join(array(
                    'subselect2' =>$subselect2),
                        'survey_responses.id = subselect2.response_id',
                        array('float_value'));

$ select-> getSqlString($ adapterPlatform);产生所需的查询:

   SELECT `survey_responses`.*, `subselect1`.`float_value` AS `float_value`, `subselect2`.`float_value` AS `float_value` FROM `survey_responses` 
   INNER JOIN (SELECT `question_responses`.* FROM `question_responses` WHERE `question_id` = '11' AND `float_value` < '2000') 
   AS `subselect1` ON `survey_responses`.`id` = `subselect1`.`response_id` 
   INNER JOIN (SELECT `question_responses`.* FROM `question_responses` WHERE `question_id` = '11' AND `float_value` > '10') 
   AS `subselect2` ON `survey_responses`.`id` = `subselect2`.`response_id` GROUP BY `id`

然而,发送MYSQL的查询和我从mysql日志中获取的是:

   SELECT `survey_responses`.*, `subselect1`.`subselect1`.`float_value` AS `subselect1.float_value`, `subselect2`.`subselect2`.`float_value` AS `subselect2.float_value` FROM `survey_responses` 
   INNER JOIN (SELECT `question_responses`.* FROM `question_responses` WHERE `question_id` = '11' AND `float_value` < '10') 
   AS `subselect1` ON `survey_responses`.`id` = `subselect1`.`response_id` 
   INNER JOIN (SELECT `question_responses`.* FROM `question_responses` WHERE `question_id` = '11' AND `float_value` > '10') 
   AS `subselect2` ON `survey_responses`.`id` = `subselect2`.`response_id` GROUP BY `id`

不同之处在于第二个中的float_values现在是相同的。

任何人都可以了解这些值如何对getSqlString更正,但查询发送到mysql有错吗?

我怎么能解决这个问题,所以mysql查询为每个子选择都有不同的float_values。

由于

ABOR。

1 个答案:

答案 0 :(得分:0)

我发现在没有覆盖的情况下创建子选择的唯一方法是为该子选择使用getSqlString并将它们连接到主查询中。

/**
 * get response by filter
 */
public function getResponsesByFilterArray($survey_id, $filter_array = NULL)
{
    $adapter = $this->tableGateway->adapter;
    $platform = new \Zend\Db\Adapter\Platform\Mysql();

    $select = new \Zend\Db\Sql\Select();
    $select->from('survey_responses');
    $select_string = $select->getSqlString($platform);

    if($filter_array !== NULL)
    {
        $filter_array_count = 0;
        foreach($filter_array as $filter_model)
        {
            $filter_array_count++;

            $subselect = new \Zend\Db\Sql\Select();
            $subselect->from('question_responses');
            $subselect->where(array('question_id' => $filter_model->question_id));

            switch($filter_model->comparison){
                case $filter_model::$EQUALS:
                    $subselect->where->equalTo('float_value', (float) $filter_model->to_value);
                    break;
                case $filter_model::$GREATER_THAN:
                    $subselect->where->greaterThan('float_value', (float) $filter_model->to_value);
                    break;
                case $filter_model::$LESS_THAN:
                    $subselect->where->lessThan('float_value', (float) $filter_model->to_value);
                    break;
                case $filter_model::$BETWEEN:
                    $subselect->where->between('float_value', (float) $filter_model->from_value , (float) $filter_model->to_value);
                    break;
            }

            $join_string = ' JOIN (%s) AS `%s` ON `survey_responses`.`id`  =  `%s`.`response_id` ';
            $sub_select_string = sprintf(
                $join_string, 
                $subselect->getSqlString($platform), 
                'subselect'.$filter_array_count,
                'subselect'.$filter_array_count
            );

            $select_string .= $sub_select_string;
        }
    }

    $where_string = ' WHERE `survey_id` = %s';
    $select_where_string = sprintf(
        $where_string,
        $survey_id
    );

    $select_string .=  $select_where_string;

    $sql = new \Zend\Db\Sql\Sql($adapter);
    $rowset = $adapter->query($select_string, $adapter::QUERY_MODE_EXECUTE);

    return $rowset;
}

希望这有助于其他人,

ABOR。