programing

코드 점화기의 활성 레코드 패턴을 사용한 UNION 쿼리

minimums 2023. 10. 20. 13:31
반응형

코드 점화기의 활성 레코드 패턴을 사용한 UNION 쿼리

PHP CodeIgniter 프레임워크의 활성 레코드 쿼리 형식으로 UNION 쿼리를 수행하는 방법은?

CodeIgniter의 ActiveRecord는 UNION을 지원하지 않으므로 쿼리를 작성하고 ActiveRecord의 쿼리 방법을 사용하면 됩니다.

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

last_query()를 사용하여 union을 수행함으로써 응용프로그램 수행에 방해가 될 수 있습니다.왜냐하면 단일 연합의 경우 3개의 쿼리를 실행해야 하기 때문입니다.즉, "n"개의 조합 "n+1"개의 쿼리에 대한 것입니다.1-2 쿼리 연합에는 큰 영향을 미치지 않을 것입니다.하지만 많은 쿼리나 데이터가 큰 테이블을 결합한다면 문제가 될 것입니다.

이 링크는 많은 도움이 될 것입니다: 활성 레코드 하위 쿼리

활성 기록과 수동 쿼리를 결합할 수 있습니다.예:

// #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();

이것은 내가 예전에 사용했던 빠르고 더러운 방법입니다.

// 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);

내 최고의 작품은 아니지만, 내 문제를 해결해 주었어요.

참고: 결과를 주문할 필요가 없었습니다.

모델에서 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 변수에 있게 됩니다.

오래전에 이 질문을 하셨기 때문에 이미 답을 얻으셨을 수도 있습니다. 그렇지 않다면 이 과정이 효과가 있을 수도 있습니다.

somnath hucks의 답변을 수정함으로써 다음과 같은 변수와 함수를 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을 가상으로 사용할 수 있습니다.

이 메서드와 함께 union을 사용하려면 일반적인 활성 레코드 쿼리를 만들지만 get 대신 union_ push를 호출합니다.

참고: 쿼리에 정규 조합처럼 일치하는 열이 있는지 확인해야 합니다.

예:

    $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`)

이 라이브러리를 찾았는데 액티브 레코드 스타일로 UNION을 추가하는 데 아주 적합했습니다.

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

하지만 나는 그것을 잡아야만 했습니다.get_compiled_select()먼저 CodeIgniter의 dev 브랜치에서 메서드를 사용합니다(여기서 사용 가능: 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 개발 버전은 사용하고 싶지 않았습니다.)

이거 드셔보세요.

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

이것이 제가 사용하고 있는 솔루션입니다.

$union_queries = array();
$tables = array('table1','table2'); //As much as you need
foreach($tables as $table){
    $this->db->select(" {$table}.row1, 
                        {$table}.row2,
                        {$table}.row3");
    $this->db->from($table);
    //I have additional join too (removed from this example)
    $this->db->where('row4',1);
    $union_queries[] = $this->db->get_compiled_select();
}
$union_query = join(' UNION ALL ',$union_queries); // I use UNION ALL
$union_query .= " ORDER BY row1 DESC LIMIT 0,10";
$query = $this->db->query($union_query);

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");

제가 만든 솔루션은 다음과 같습니다.

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

언급URL : https://stackoverflow.com/questions/2040655/union-query-with-codeigniters-active-record-pattern

반응형