PHP CodeIgniterフレームワークのアクティブレコードクエリ形式でUNIONクエリを実行するにはどうすればよいですか?
10 に答える
CodeIgniter の ActiveRecord は UNION をサポートしていないため、クエリを記述して ActiveRecord の query メソッドを使用するだけです。
$this->db->query('SELECT column_name(s) FROM table_name1 UNION SELECT column_name(s) FROM table_name2');
last_query() を使用してユニオンを行うと、アプリケーションのパフォーマンスが低下する可能性があります。単一のユニオンの場合、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 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 に依存せずに共用体を仮想的に使用できます。
このメソッドでユニオンを使用するには、通常のアクティブ レコード クエリを作成するだけですが、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`)
このライブラリは、ActiveRecord スタイルで 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 の将来の製品リリースで利用できるようになるでしょう。
そのメソッドを system/database の DB_active_rec.php に追加すると、それは魅力的に機能しました。(これは本番アプリであるため、CodeIgniter の開発バージョンは使用しませんでした。)
私が作成したソリューションは次のとおりです。
$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);