제목 | ci4 액티브 레코드 subquery union compileSelect 작동방식은 ? | ||
---|---|---|---|
카테고리 | CI 4 관련 | ||
글쓴이 | darkninja | 작성시각 | 2022/11/27 15:23:33 |
|
|||
->select("b.username, a.table, a.board_table, a.comment_table, ".$u_field, false) $sql = $builder->getCompiledSelect(false); $query = $builder->get(); 위에 처럼 하면 sql에 값이 b.username 에 넘어오지 않고 아래 처럼 하면 되는 것 같은데 ... $sql = $builder->getCompiledSelect(); $query = $builder->get(null,0,false); getCompiledSelect(bool $reset = true): string 에서 호출하는 resetSelect() 에서 뭔가를 하는 것 닽은데 ... 고수님들 설명을 부탁 드립니다. fromSubquery 두개 사용은 안되는 거 같습니다;; 정상적인 결과가 안 나오네요. 하나만 사용시에는 모든게 정상입니다. fromSubquery 을 join 으로 바꾸니 제대로 됩니다 sql 에 기본적인 지식이 없다보니..
$sql = $builder->getCompiledSelect(); // 이줄을 첨가하지 않으면 에러 납니다. $query = $builder->get(null,0,false); if ($query->getNumRows() > 0) { $cnt = $query->getNumRows(); } $builder->limit($per_page, ($page_index - 1) * $per_page); $query = $builder->get(); return $query->getResult();
public function all_search_paginated_active($search_table, $search_field, $field_or, $text_or, $search_text, $page_index=1, $per_page=10, &$cnt=0) { $union = $this->all_search_paginated_union($search_table, $search_field, $field_or, $text_or, $search_text); $user_subquery = $this->db ->table("users"); $u_field = " `a`.`id`, `a`.`user_id`, `a`.`user_name`, `a`.`category_name`, `a`.`subject`, `a`.`reply_count`, `a`.`reg_date`, `a`.`modify_date`, `a`.`contents`, `a`.`tag`"; $builder = $this->db ->newQuery() ->select("users.username, a.table, a.board_table, a.comment_table, ".$u_field, false) ->fromSubquery($union, "a"); //->fromSubquery($user_subquery, "b") ->join("users", "users.id = a.user_id"); //->orderBy("reg_date", "desc"); //$sql = $builder->getCompiledSelect(false); //$sql = $builder->getCompiledSelect(); //$query = $builder->get(); $query = $builder->get(null,0,false); if ($query->getNumRows() > 0) { $cnt = $query->getNumRows(); } //echo $sql; echo $this->db->GetLastQuery(); echo '<br>'; echo $cnt; echo '<br>'; echo '<br>'; //$builder = $this->db // ->newQuery() // ->select("b.username, a.table, a.board_table, a.comment_table, ".$u_field, false) // ->fromSubquery($union, "a") // ->fromSubquery($user_subquery, "b") // ->where("a.user_id", "b.id") // ->orderBy("reg_date", "desc") // //->limit($per_page, ($page_index - 1) * $per_page) // ; //$sql = $builder->getCompiledSelect(); $builder->orderBy("modify_date", "desc"); $builder->limit($per_page, ($page_index - 1) * $per_page); $query = $builder->get(); //$query = $builder->get($per_page, ($page_index - 1) * $per_page); //echo $sql; echo $this->db->GetLastQuery(); echo '<br>'; echo '<br>'; return $query->getResult(); } public function all_search_paginated_union($search_table, $search_field, $field_or, $text_or, $search_text) { $s_field = " `id`, `user_id`, `user_name`, `category_name`, `subject`, `reply_count`, `reg_date`, `modify_date`, `contents`, `tag` "; $union = 0; if (is_array($search_table)) { foreach($search_table as $table) { $builder = $this->db ->table($table) ->select("'".$table."' as `table`, '".$table."' as `board_table`, '".$table."_comment' as `comment_table`, ".$s_field, false); $builder = $this->search_orlike($builder, $search_table, $search_field, $field_or, $text_or, $search_text); $builder->orderBy('id', 'DESC'); if ($union) { $union = $union->union($builder); } else { $union = $builder; } } } else { $builder = $this->db ->table($table) ->select("'".$search_table."' as `table`, '".$search_table."' as `board_table`, '".$search_table."_comment' as `comment_table`, ".$s_field, false); $builder = $this->search_orlike($builder, $search_table, $search_field, $field_or, $text_or, $search_text); $builder->orderBy('id', 'DESC'); $union = $builder; } return $union; } public function search_orlike($builder, $search_table, $search_field, $field_or, $text_or, $search_text) { $f = ""; $t = ""; if (is_array($search_field)) { if (is_array($search_text)) { foreach($search_field as $field) { if ($field_or == "or") { $builder->orGroupStart(); } else { $builder->GroupStart(); } foreach($search_text as $text) { if ($text_or =='or') { $builder->orLike($field, $text); } else { $builder->Like($field, $text); } } $builder->GroupEnd(); } } else { foreach($search_field as $field) { if ($field_or == "or") { $builder->orGroupStart(); } else { $builder->GroupStart(); } if ($field_or =='or') { $builder->orLike($field, $search_text); } else { $builder->Like($field, $search_text); } $builder->GroupEnd(); } } } else { if (is_array($search_text)) { $builder->GroupStart(); foreach($search_text as $text) { if ($text_or =='or') { $builder->orLike($search_field, $text); } else { $builder->Like($search_field, $text); } } $builder->GroupEnd(); } else { if ($text_or =='or') { $builder->orLike($search_field, $search_text); } else { $builder->Like($search_field, $search_text); } } } return $builder; } public function getCompiledSelect(bool $reset = true): string { $select = $this->compileSelect(); if ($reset === true) { $this->resetSelect(); } return $this->compileFinalQuery($select); } protected function resetSelect() { $this->resetRun([ 'QBSelect' => [], 'QBJoin' => [], 'QBWhere' => [], 'QBGroupBy' => [], 'QBHaving' => [], 'QBOrderBy' => [], 'QBNoEscape' => [], 'QBDistinct' => false, 'QBLimit' => false, 'QBOffset' => false, 'QBUnion' => [], ]); if (! empty($this->db)) { $this->db->setAliasedTables([]); } // Reset QBFrom part if (! empty($this->QBFrom)) { $this->from(array_shift($this->QBFrom), true); } } public function from($from, bool $overwrite = false): self { if ($overwrite === true) { $this->QBFrom = []; $this->db->setAliasedTables([]); } foreach ((array) $from as $table) { if (strpos($table, ',') !== false) { $this->from(explode(',', $table)); } else { $table = trim($table); if ($table === '') { continue; } $this->trackAliases($table); $this->QBFrom[] = $this->db->protectIdentifiers($table, true, null, false); } } return $this; }
|
|||
다음글 | 관리자 페이지 로그인이 한번에 안되는 문제 (1) | ||
이전글 | CI3 조회페이지에서 $CI->db->tra... (1) | ||
한대승(불의회상)
/
2022/11/28 15:32:28 /
추천
0
|
darkninja
/
2022/11/28 18:51:42 /
추천
0
포럼 구버젼의 소스에서 검색하는 부분을 조금 달리 한건데 로컬에서 마구 수집한 자료를 검색하는 용도로 만들려고 하는 중입니다 http://localhost/ci-426/index.php/Search/view_all_active/farm,gam/subject,contents/or/or/simple/%EA%B0%90,%ED%83%9C%EC%B6%94 조인하는 부분은 없어도 되는데 포럼구버젼소스를 그대로 바꾸려고 하다보니 엉뚱하게 진행되었습니다
같은 구조로 된 여러개의 테이블에서 제목이나 본문에 있는 여러개의 문자열을 검색하는 용도입니다 에러난 부분은 조인으로 바꾸어서 해결되었습니다
컨트롤러 호출부분입니다 public function view_all_active($search_table, $search_field, $field_or, $text_or, $simple_list="", $search_text="", $page_index=1) { if (empty($search_text)) { $this->response->redirect(site_url('/')); } session_set_search($search_table, $search_field, $field_or, $text_or, $search_text, $page_index); $search_text_encode = $search_text; $search_text_decode = $search_text; $text_encode = $this->session->get('text_encode'); if ($text_encode == "myencode") { $search_text_decode = decode_str_array($search_text); } else if ($text_encode == "urlencode") { $search_text_decode = urldecode($search_text); } $table_array = explode(',', $search_table); $field_array = explode(',', $search_field); $text_array_decode = explode(',', $search_text_decode); //search_text_decode if ($simple_list == "") { $simple_list = $this->session->get('simple_list'); } $this->session->set('simple_list', $simple_list); if ($simple_list == "simple") { $per_page = $this->per_page; $view_name = "search_all"; $url_name = "view_all_active"; $view_simple_list = "list"; } else { $per_page = $this->per_page_list; $view_name = "searchlist_all"; $url_name = "view_all_active"; $view_simple_list = "simple"; } $Surround_Count = $this->Surround_Count; $cnt = 0; $boards = $this->board_model->all_search_paginated_active($table_array, $field_array, $field_or, $text_or, $text_array_decode, $page_index, $per_page, $cnt); $redirect_url = 'search/'.$url_name.'/'.$search_table.'/'.$search_field.'/'.$field_or.'/'.$text_or.'/'.$simple_list.'/'.$search_text_encode; $pager_base_url = ROOT_PATH.'/'.$redirect_url; $page = $page_index; $total_rows = $cnt; $template_name = 'default_full'; $uri_segment = 10; $group = 'default'; //$pager = $this->board_model->pager; $pager = service('pager'); $pager->setPath($pager_base_url, $group); // Additionally you could define path for every group. $pageLinks = $pager->makeLinks($page, $per_page, $total_rows, $template_name, $uri_segment, $group); $t = intval(($total_rows-1) / $per_page) + 1; if ($page_index > $t) { $this->response->redirect(site_url($redirect_url.'/'.$t)); } $data = Array( 'head_data' => Array( 'title' => '통합검색 : '.$search_text_decode, ), 'view_data' => Array( 'boards' => $boards, 'pageLinks' => $pageLinks, 'Surround_Count' => $Surround_Count, 'session' => $this->session, 'db' => $this->db, 'cut_contents' => $this->cut_contents, 'board_controller' => $this->board_controller, 'search_controller' => $this->search_controller, 'search_table' => $search_table, 'search_field' => $search_field, 'field_or' => $field_or, 'text_or' => $text_or, 'simple_list' => $view_simple_list, 'search_text_encode' => $search_text_encode, 'page_index' => $page_index, 'url_name' => $url_name, 'no_more_board' => '', ), ); $data = array_replace_recursive($this->data, $data); if ($total_rows <= $per_page) { $view_data['no_more_board'] = 'no more board !'; } $this->render_page($view_name, $data); }
|
한대승(불의회상)
/
2022/11/29 18:27:39 /
추천
0
mysql은 서브쿼리보다 join의 성능이 좋아서 가능하면 서브쿼리를 join으로 변환하도록 가이드합니다. 문제 해결을 위해 많은 수고를 하셨네요. |
올려주신 코드로는 정확히 무엇을 하고 싶은지 잘 이해가 안되는군요.
서브 쿼리에 관련된 부분은 메뉴얼에 잘 나와 있습니다.
http://ci4doc.cikorea.net/database/query_builder.html#subqueries
샘플 쿼리와 아래 주석으로 표시된 결과를 잘 확인하시면 원하시는 쿼리를 만들어 내실수 있을겁니다.