具有codeigniter活动记录模式的UNION查询

时间:2010-01-11 08:37:03

标签: mysql sql codeigniter activerecord union

如何使用PHP CodeIgniter框架的活动记录查询格式进行UNION查询?

10 个答案:

答案 0 :(得分:32)

CodeIgniter的ActiveRecord不支持UNION,因此您只需编写查询并使用ActiveRecord的查询方法。

$this->db->query('SELECT column_name(s) FROM table_name1 UNION SELECT column_name(s) FROM table_name2');

答案 1 :(得分:22)

这是我曾经使用的一种快速而肮脏的方法

// Query #1

$this->db->select('title, content, date');
$this->db->from('mytable1');
$query1 = $this->db->get()->result();

// Query #2

$this->db->select('title, content, date');
$this->db->from('mytable2');
$query2 = $this->db->get()->result();

// Merge both query results

$query = array_merge($query1, $query2);

不是我最好的工作,但它解决了我的问题。

注意:我不需要订购结果。

答案 2 :(得分:19)

通过使用last_query()进行联合,可能会妨碍应用程序的性能。因为对于单个联合,它将需要执行3个查询。即“n”联合“n + 1”查询。它对1-2查询联合没什么影响。但是,如果许多查询或表具有大数据的联合,它将会产生问题。

此链接可以为您提供很多帮助:active record subqueries

我们可以将活动记录与手动查询相结合。 例如:

// #1 SubQueries no.1 -------------------------------------------

$this->db->select('title, content, date');
$this->db->from('mytable');
$query = $this->db->get();
$subQuery1 = $this->db->_compile_select();

$this->db->_reset_select();

// #2 SubQueries no.2 -------------------------------------------

$this->db->select('title, content, date');
$this->db->from('mytable2');
$query = $this->db->get();
$subQuery2 = $this->db->_compile_select();

$this->db->_reset_select();

// #3 Union with Simple Manual Queries --------------------------

$this->db->query("select * from ($subQuery1 UNION $subQuery2) as unionTable");

// #3 (alternative) Union with another Active Record ------------

$this->db->from("($subQuery1 UNION $subQuery2)");
$this->db->get();

答案 3 :(得分:8)

您可以使用以下方法在模型中获取SQL语句:

$this->db->select('DISTINCT(user_id)');
$this->db->from('users_master');
$this->db->where('role_id', '1');

$subquery = $this->db->_compile_select();
$this->db->_reset_select();

这样,SQL语句将在$ subquery变量中,而不实际执行它。

很久以前你问过这个问题,所以也许你已经得到了答案。如果没有,这个过程可能会成功。

答案 4 :(得分:3)

通过修改somnath huluks的答案,我将以下变量和函数添加到DB_Active_rec类中,如下所示:

class DB_Active_records extends CI_DB_Driver
{

   ....

   var $unions;

   ....

    public function union_push($table = '')
    {
        if ($table != '')
        {
            $this->_track_aliases($table);
            $this->from($table);
        }

        $sql = $this->_compile_select();

        array_push($this->unions, $sql);
        $this->_reset_select();
    }

    public function union_flush()
    {
        $this->unions = array();
    }

    public function union()
    {
        $sql = '('.implode(') union (', $this->unions).')';
        $result = $this->query($sql);
        $this->union_flush();
        return $result;
    }

    public function union_all()
    {
        $sql = '('.implode(') union all (', $this->unions).')';
        $result = $this->query($sql);
        $this->union_flush();
        return $result;
    }
}

因此,您几乎可以使用不依赖于db_driver的联合。

使用与此方法的联合,您只需进行常规的活动记录查询,但调用union_push而不是get。

注意:您必须确保您的查询具有匹配的列,例如常规联合

示例:

    $this->db->select('l.tpid, l.lesson, l.lesson_type, l.content, l.file');
    $this->db->where(array('l.requirement' => 0));
    $this->db->union_push('lessons l');
    $this->db->select('l.tpid, l.lesson, l.lesson_type, l.content, l.file');
    $this->db->from('lessons l');
    $this->db->join('scores s', 'l.requirement = s.lid');
    $this->db->union_push();
    $query = $this->db->union_all();
    return $query->result_array();

会产生:

(SELECT `l`.`tpid`, `l`.`lesson`, `l`.`lesson_type`, `l`.`content`, `l`.`file`
FROM `lessons` l
WHERE `l`.`requirement`=0)
union all 
(SELECT `l`.`tpid`, `l`.`lesson`, `l`.`lesson_type`, `l`.`content`, `l`.`file`
FROM `lessons` l
JOIN `scores` s ON `l`.`requirement`=`s`.`lid`)

答案 5 :(得分:2)

我找到了这个库,它很适合我以ActiveRecord样式添加UNION:

https://github.com/NTICompass/CodeIgniter-Subqueries

但我必须首先从CodeIgniter的dev分支中获取get_compiled_select()方法(此处可用:https://github.com/EllisLab/CodeIgniter/blob/develop/system/database/DB_query_builder.php - DB_query_builder将替换DB_active_rec)。据推测,这种方法将在CodeIgniter的未来生产版本中提供。

一旦我将该方法添加到系统/数据库中的DB_active_rec.php,它就像一个魅力。 (我不想使用开发版的CodeIgniter,因为这是一个生产应用程序。)

答案 6 :(得分:1)

尝试这个

function get_merged_result($ids){                   
    $this->db->select("column");
    $this->db->distinct();
    $this->db->from("table_name");
    $this->db->where_in("id",$model_ids);
    $this->db->get(); 
    $query1 = $this->db->last_query();

    $this->db->select("column2 as column");
    $this->db->distinct();
    $this->db->from("table_name");
    $this->db->where_in("id",$model_ids);

    $this->db->get(); 
    $query2 =  $this->db->last_query();
    $query = $this->db->query($query1." UNION ".$query2);

    return $query->result();
}

答案 7 :(得分:1)

这是我正在使用的解决方案:

select DATEADD(dd,-60,cast(20161231 as varchar(10)))

答案 8 :(得分:0)

bwisn的答案比所有答案都好,并且可以工作,但性能不佳,因为它将首先执行子查询。 get_compiled_select 不运行查询;它只是将其编译以供以后运行,因此速度更快 试试这个

$this->db->select('title, content, date');
$this->db->where('condition',value);
$query1= get_compiled_select("table1",FALSE);
$this->db->reset_query();

$this->db->select('title, content, date');
$this->db->where('condition',value);
$query2= get_compiled_select("table2",FALSE);
$this->db->reset_query();

$query = $this->db->query("$query1 UNION $query2");

答案 9 :(得分:-1)

这是我创建的解决方案:

$query1 = $this->db->get('Example_Table1');
$join1 = $this->db->last_query();
$query2 = $this->db->get('Example_Table2');
$join2 = $this->db->last_query();
$union_query = $this->db->query($join1.' UNION '.$join2.' ORDER BY column1,column2);