Requête de L'UNION avec le modèle d'enregistrement actif de codeigniter
Comment faire une requête UNION avec le format de requête active record de PHP CodeIgniter framework?
10 réponses
ActiveRecord de CodeIgniter ne supporte pas L'UNION, donc vous n'avez qu'à écrire votre requête et utiliser la méthode de requête ActiveRecord.
$this->db->query('SELECT column_name(s) FROM table_name1 UNION SELECT column_name(s) FROM table_name2');
C'est un moyen rapide et sale méthode une fois, j'ai utilisé
// 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);
pas mon meilleur travail, mais il a résolu mon problème.
note: je n'ai pas besoin de commander le résultat.
en faisant union en utilisant last_query (), cela peut nuire à la performance de l'application. Parce que pour une seule union il faudrait exécuter 3 requêtes. j'.e pour le "n" de l'union "n+1" requêtes. Cela n'affectera pas beaucoup pour 1-2 query union. Mais cela posera problème si l'union de plusieurs requêtes ou tableaux ayant de grandes données.
ce lien vous aidera beaucoup:enregistrement actif sous-requêtes
nous pouvons combiner l'enregistrement actif avec des requêtes manuelles. Exemple:
// #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();
Vous pouvez utiliser la méthode suivante pour obtenir la déclaration SQL dans le model:
$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();
de cette façon L'instruction SQL sera dans la variable $subquery, sans l'exécuter réellement.
Vous avez posé cette question il y a longtemps, donc peut-être avez-vous déjà la réponse. si pas, ce processus peut faire l'affaire.
en modifiant la réponse de somnath huluks, j'ajoute ces variables et fonctions suivantes à la classe DB_Active_rec comme suit:
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;
}
}
par conséquent, vous pouvez virtuellement utiliser des unions sans liens de dépendance avec db_driver.
pour utiliser union avec cette méthode, il vous suffit de faire des requêtes active record régulières, mais en appelant union_push au lieu de get.
note: vous devez vous assurer que vos requêtes ont des colonnes correspondantes comme régulière les syndicats
exemple:
$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();
donnerait:
(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`)
j'ai trouvé cette bibliothèque, qui a bien fonctionné pour moi d'ajouter UNION dans un style ActiveRecord:
https://github.com/NTICompass/CodeIgniter-Subqueries
MAIS j'ai eu à prendre la get_compiled_select()
méthode de la branche dev de CodeIgniter d'abord (disponible ici: https://github.com/EllisLab/CodeIgniter/blob/develop/system/database/DB_query_builder.php -- DB_query_builder remplacera DB_active_rec). Probablement cette méthode sera disponible dans une future production de CodeIgniter.
Une fois que J'ai ajouté cette méthode à DB_active_rec.php dans le système / base de données cela a fonctionné comme un charme. (Je ne voulais pas utiliser la version dev de CodeIgniter car il s'agit d'une application de production.)
essayer celui-ci
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();
}
Voici la solution que j'utilise:
$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);
la réponse de bwisn est meilleure que toutes les autres et fonctionnera mais pas très bien en performance car elle exécutera les requêtes secondaires en premier. get_compiled_select n'exécute pas la requête; il la compile pour l'exécuter plus tard donc est plus rapide essayez celui-ci
$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");
Voici une solution que j'ai créée:
$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);