简体   繁体   English

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

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

I'm trying to build a UNION query using Kohana's query builder . 我正在尝试使用Kohana的查询构建器构建 UNION查询。 Everything works fine until I add a GROUP BY or ORDER BY clause. 一切正常,直到我添加GROUP BY或ORDER BY子句。

Here is the code I'm using (simplified): 这是我正在使用的代码(简化):

$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();

Instead of adding the GROUP BY and ORDER BY at the end of the entire query, it's adding it immediately after the second query. 它不是在整个查询结束时添加GROUP BY和ORDER BY,而是在第二个查询之后立即添加它。

This is the SQL this generates: 这是生成的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;

What I want is: 我想要的是:

 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;

The clauses here are applied from the first query set up in the union() method, so just reverse where you're putting them: 这里的子句是从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();

You can also remove that superfluous ->limit(10) from $names since it will be ignored and superseded by the one in $query1 . 您还可以从$names删除多余的->limit(10) ,因为它将被忽略并被$query1的一个取代。

That answer from 2011 isn't working in Kohana 3.3. 2011年的答案在Kohana 3.3中无效。

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

You can also extend Kohana_ORM using ORM's db_pending: 您还可以使用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;
    }
}

Usage: 用法:

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']);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM