| 제목 | 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
<?php $subquery = $db->table('users'); $builder = $db->table('jobs')->fromSubquery($subquery, 'alias'); $query = $builder->get(); // Produces: SELECT * FROM `jobs`, (SELECT * FROM `users`) `alias`샘플 쿼리와 아래 주석으로 표시된 결과를 잘 확인하시면 원하시는 쿼리를 만들어 내실수 있을겁니다.