代码之家  ›  专栏  ›  技术社区  ›  Lars Nyström

Zend\Db:从子查询中选择

  •  0
  • Lars Nyström  · 技术社区  · 11 年前

    我正在将一个应用程序从ZF1移植到ZF2,作为其中的一部分,我必须重写我们的数据库映射器。

    我很难理解SQL语句:

    SELECT full_name, GROUP_CONCAT(value)
    FROM (
       SELECT full_name, value
       FROM my_table
       ORDER BY id DESC
       ) as subtable
    GROUP BY full_name
    ORDER BY full_name DESC;
    

    我试图解决的根本问题是,在运行子查询之前,我需要对子查询的结果进行排序 GROUP_CONCAT 我需要它同时适用于MySQL和Sqlite。在MySQL中,我可以简单地指定 组_类别 函数,但这在Sqlite中是不可能的,因此我需要子查询使其与MySQL和Sqlite兼容。

    在ZF1中,我可以做到:

    $fromSql = $db->select()
                  ->from('my_table', array('full_name', 'value'))
                  ->order('id DESC');
    
    $sql = $db->select()
              ->from(array(
                    'subtable' => new Zend_Db_Expr('(' . $fromSql . ')')
                ), array(
                    'full_name' => 'full_name',
                    'value' => new Zend_Db_Expr('GROUP_CONCAT(subtable.value)'),
                )
              )
              ->group('full_name')
              ->order('full_name DESC');
    

    然而,ZF2似乎不可能在from子句中使用子查询。这有什么办法吗?

    1 回复  |  直到 11 年前
        1
  •  8
  •   Community Mohan Dere    9 年前

    编辑 :实际上,我现在发现我的查询有缺陷。它不能像MySQL那样工作,这意味着我仍然需要编写专门的查询。看见 GROUP_CONCAT change GROUP BY order


    通过代码后 Zend\Db\Sql\Select 我找到了这些线条:

    if ($table instanceof Select) {
        $table = '(' . $this->processSubselect($table, $platform, $driver, $parameterContainer) . ')';
    } else {
        $table = $platform->quoteIdentifier($table);
    }
    

    所以答案其实很简单,我所要做的就是提供一个 Zend\Db\Sql\选择 反对 from() ,而不将其包装在 Zend\Db\Sql\Expression 就像我以前用ZF1时一样。

    代码示例:

    $adapter = $this->getAdapter(); // Returns Zend\Db\Adapter\Adapter
    $sql = new Zend\Db\Sql\Sql($adapter);
    
    $from = $sql->select()
        ->from(static::$table)
        ->columns(array(
            'full_name',
            'value',
        ))
        ->order('id DESC');
    
    $select = $sql->select()
        ->from(array(
            'subtable' => $from,
        ))
        ->columns(array(
            'full_name' => 'full_name',
            'value' => new Expression('GROUP_CONCAT(value)'),
        ))
        ->group('full_name')
        ->order('full_name DESC');
    
    $selectString = $sql->getSqlStringForSqlObject($select);
    
    $resultSet = $adapter->query($selectString, $adapter::QUERY_MODE_EXECUTE);
    
    return $resultSet->toArray();
    
    推荐文章