如何在 Kohana 的查询生成器中使用 ORDER BY 和 GROUP BY 构建 UNION 查询


How do I build a UNION query with ORDER BY and GROUP BY in Kohana's query builder?

我正在尝试使用Kohana的查询生成器构建一个UNION查询。一切正常,直到我添加 GROUP BY 或 ORDER BY 子句。

这是我正在使用的代码(简化(:

$query1 = DB::select('p.name')
    ->from(array('person', 'p'))
    ->where('p.organization', 'LIKE', 'foo%')
    ->limit(10);
$names = DB::select('sh.name')
    ->union($query1, FALSE)
    ->from(array('stakeholder', 'sh'))
    ->where('sh.organization', 'LIKE', 'foo%')
    ->group_by('name')
    ->order_by('name')
    ->limit(10)
    ->execute()
    ->as_array();

它不是在整个查询的末尾添加 GROUP BY 和 ORDER BY,而是在第二个查询之后立即添加它。

这是生成的 SQL:

 SELECT sh.name FROM stakeholder AS sh WHERE sh.organization LIKE 'foo%' 
 GROUP BY name ORDER BY name LIMIT 10
 UNION
 SELECT p.name from person AS p WHERE p.organization LIKE 'foo%' LIMIT 10;

我想要的是:

 SELECT sh.name FROM stakeholder AS sh WHERE sh.organization LIKE 'foo%'
 UNION
 SELECT p.name from person AS p WHERE p.organization LIKE 'foo%'
 GROUP BY name ORDER BY name LIMIT 10;

这里的子句是从 union() 方法中设置的第一个查询开始应用的,因此只需将它们放在位置相反:

$query1 = DB::select('p.name')
              ->from(array('person', 'p'))
              ->where('p.organization', 'LIKE', 'foo%')
              ->group_by('name')
              ->order_by('name')
              ->limit(10);
$names = DB::select('sh.name')
              ->union($query1, FALSE)
              ->from(array('stakeholder', 'sh'))
              ->where('sh.organization', 'LIKE', 'foo%')
              ->execute()
              ->as_array();

您还可以从$names中删除多余的->limit(10),因为它将被忽略并被$query1中的那个所取代。

您还可以

使用ORM的db_pending扩展Kohana_ORM:

class ORM extends Kohana_ORM {
    public function union($table, $all = TRUE)
    {
        // Add pending database call which is executed after query type is determined
        $this->_db_pending[] = array(
            'name' => 'union',
            'args' => array($table, $all),
        );
        return $this;
    }
}

用法:

ORM::factory('MyModel')
    ->union(DB::select(DB::expr("'RP' id, 'Pasantías' name, 'Pasantías' short_name, 'R' parent_id, null data")))
    ->union(DB::select(DB::expr("'RC' id, 'Capacitación' name, 'Capacitación' short_name, 'R' parent_id, null data")))
    ->join(['catalogo', 'p'])->on('catalogo.parent_id', '=', 'p.id')
    ->where('p.parent_id', 'is', NULL)
    ->where('catalogo.id', 'not in', ['RV', 'RPA', 'RPT']);

> 2011 年的答案在 Kohana 3.3 中不起作用。

但我找到了这个模块:https://github.com/Invision70/kohana-orm-union