我正在将应用程序从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中,我可以简单地指定GROUP_CONCAT
函数中的顺序,但这对于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子句中使用子查询。有没有解决这个问题?
答案 0 :(得分:6)
编辑:实际上,我现在看到我的查询存在缺陷。它不会像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\Select
提供一个from()
对象,而不像我以前用ZF1那样将它包裹在Zend\Db\Sql\Expression
中。
代码示例:
$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();