-
[CI] active record로 subquery 사용PHP 2020. 8. 12. 10:29
쿼리문을 짤 때, 서브쿼리를 생각보다 많이 사용하게 된다.
조인을 해서 Full table scan을 피하려면 그래도 서브쿼리가 속도면에서도 더 좋은 것 같다.
이 부분에 대한 고민은 좀 더 스터디가 필요하다.
그렇게 서브쿼리로 쿼리문을 짜다보니
$this->db->select("*"); $this->db->from($this->b_a_db.".bio_question ques"); $this->db->where('ques.paper_id','(select paper_id from bio_admin.bio_reservation where rs_key = (select rs_key from bio.bio_tester where tester_id='.$this->session->userdata('tester_id').'))',false); $this->db->where('ques.q_num',$q_real_num); $query = $this->db->get()->row_array();
가로스크롤이 엄청나게 생겨나는 이런식의 구문이 탄생하게 되었다.
코드가 직관적이지도 않고, 뭔가 수정하고 싶은 욕구가 계속해서 생겨나는 중..
검색을 해보니 get_compiled_select() 로 서브쿼리를 깔끔하게 넣어주는 active record 문법이 있었다.
$superSubQuery = $this->db->select('rs_key') ->from($this->b_db.'.bio_tester') ->where('tester_id', $this->session->userdata('tester_id')) ->get_compiled_select(); $subQuery = $this->db->select('paper_id') ->from($this->b_a_db.'.bio_reservation') ->where('rs_key IN ('.$superSubQuery.')', NULL, FALSE) ->get_compiled_select(); $query = $this->db->select("*") ->from($this->b_a_db.".bio_question q") ->where('q.paper_id IN ('.$subQuery.')', NULL, FALSE) ->where('q.q_num', $q_real_num) ->get() ->row_array();
물론 라인 수는 더 길어졌지만, 좀 더 직관적인 코드가 되었다.
클린코드에서 코드를 소설읽듯이 읽히도록 구성하라는 메세지가 자꾸만 떠올라서 나는 요즘 코드가 길어져도
내가 아닌 내 코드를 볼 다른 사용자들을 위해 코드를 구성하려고 한다.
$this->db->get_compiled_select()
셀렉트 쿼리를 $this->db->get()와 같이 컴파일하지만, 쿼리를 실행하지는 않습니다.
이 함수는 단지 SQL 쿼리를 문자열로 반환합니다.$sql = $this->db->get_compiled_select('mytable'); echo $sql; // Prints string: SELECT * FROM mytable
두 번째 파라미터는 쿼리 빌더를 재설정할지 결정합니다. (기본적으로 $this->db->get()를 사용하는 것처럼 재설정됩니다):
echo $this->db->limit(10,20)->get_compiled_select('mytable', FALSE); // Prints string: SELECT * FROM mytable LIMIT 20, 10 // (in MySQL. Other databases have slightly different syntax) echo $this->db->select('title, content, date')->get_compiled_select(); // Prints string: SELECT title, content, date FROM mytable LIMIT 20, 10
위의 예제에서 알 수 있는 중요한 것은,
두 번째 쿼리는 $this->db->from()를 사용하지 않았고, 테이블명을 첫 번째 파라미터로 전달하지 않았다는 것입니다.
이 결과에 대한 이유는 쿼리가 값을 초기화하는 $this->db->get()를 사용하지 않았기 때문입니다.[참조]
http://www.ciboard.co.kr/user_guide/kr/database/query_builder.html
Query Builder Class ‐ 코드이그나이터 3.0 한글매뉴얼
TRUE on success, FALSE on failure
www.ciboard.co.kr
'PHP' 카테고리의 다른 글
Active Record에서 insert() 반환값 (0) 2020.07.28