Jak wykonać zapytanie UNION z aktywnym formatem rekordów PHP CodeIgniter?Zapytanie UNION z aktywnym wzorcem rekordu codeigniter
Odpowiedz
ActiveRecord CodeIgniter nie obsługuje UNION, więc wystarczy napisać zapytanie i skorzystać z metody kwerendy ActiveRecord.
$this->db->query('SELECT column_name(s) FROM table_name1 UNION SELECT column_name(s) FROM table_name2');
Oto rozwiązanie stworzyłem:
$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);
To naprawdę nie jest "serwer" wydajne, ponieważ wykonujesz 2 niepotrzebne zapytania przed UNION. –
Mam rozwiązanie wydajne rozwiązanie i podałem odpowiedź. –
Możesz skorzystać z następujących metod, aby uzyskać SQL w modelu
$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();
ten sposób SQL będzie w zmienna podkwerendy $, bez faktycznego jej wykonywania.
Zadałeś to pytanie dawno temu, więc może masz już odpowiedź. jeśli nie, proces ten może załatwić sprawę.
'_compile_select()' jest metodą chronioną w najnowszej wersji CodeIgniter (podkreślenie oznacza, że była ona przeznaczona przede wszystkim jako metoda wewnętrzna). Zobacz moją odpowiedź na obejście: http://stackoverflow.com/a/14270008/560114 –
Wykonując połączenie za pomocą last_query(), może to utrudnić działanie aplikacji. Ponieważ dla pojedynczego związku wymagałoby to wykonania 3 zapytań. np. dla zapytań "n" związkowych "n + 1". Nie wpłynie to zbytnio na 1-2 połączenie zapytania. Ale da to problem, jeśli połączenie wielu zapytań lub tabel posiadających duże dane.
Ten link będzie Ci dużo: active record subqueries
Możemy połączyć aktywny rekord z ręcznymi zapytaniami. Przykład:
// #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();
jaki jest pożytek z => '$ query = $ this-> db-> get();'? $ query nie wydaje się używać w dowolnym miejscu kodu. –
Fantastyczne! Dobry pomysł. To prawdziwy związek. Drugi uruchamia 2 zapytania w bazie danych. Czasami zastanawiam się, czy deweloperzy dbają o wydajność bazy danych. –
Jest to szybki i brudny sposób ja kiedyś
// 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);
Nie moja najlepsza praca, ale to rozwiązać mój problem.
Uwaga: Nie trzeba było zamawiać wyników.
Znalazłem tej biblioteki, który pracował dobrze dla mnie, aby dodać Unii w stylu ActiveRecord:
https://github.com/NTICompass/CodeIgniter-Subqueries
ale miałem pierwszy (dostępny chwycić metodę z branży dev z CodeIgniter get_compiled_select()
tutaj: https://github.com/EllisLab/CodeIgniter/blob/develop/system/database/DB_query_builder.php - DB_query_builder będzie zastępował DB_active_rec). Prawdopodobnie ta metoda będzie dostępna w przyszłej wersji produkcyjnej CodeIgniter.
Po dodaniu tej metody do DB_active_rec.php w systemie/bazie danych działało jak czar. (. Nie chciałem użyć wersji dev CodeIgniter ponieważ jest to aplikacja produkcja)
Zrobiłem tę bibliotekę, dziękuję za jej użycie :-) –
Jestem tutaj w dylemacie i potrzebuję wyjaśnienia. Czy dodanie metody 'get_compiled_select' w' DB_active_rec.php' spowoduje, że biblioteka będzie działać poprawnie? Czy musimy używać dodanej metody do łączenia wyników? Nie widzę żadnej wzmianki o tej metodzie w repozytorium GitHub biblioteki, o której wspomniałeś podczas wykonywania UNION. I czy wykona UNION ALL? – SilentAssassin
@RocketHazmat: Zobacz powyższy komentarz i wyjaśnij moją wątpliwość. Nie mogę uruchomić zapytania UNION ALL zgodnie z twoim przykładem. – SilentAssassin
modyfikując Somnath huluks odpowiedź, dodam te następujące zmienne i funkcje klasy DB_Active_rec następująco:
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;
}
}
w związku z tym można praktycznie używać związków bez zależności do db_driver.
używać unii przy pomocy tej metody, po prostu tworzysz regularne aktywne zapytania rekordów, ale wywołuje union_push zamiast get.
uwaga: trzeba zapewnić wasze pytania mają pasujące kolumny jak zwykłe związki
przykład:
$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();
przyniosłoby:
(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`)
próbować ten jeden
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();
}
Zły pomysł, jeśli dane zmieniają się w jakiś proces asynchroniczny, dane mogą zostać dodane/usunięte/zmienione między dwoma zapytaniami. – user9645
To jest rozwiązanie, którego używam:
$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);
- 1. UNION na zapytanie JPA
- 2. Codeigniter - Zamawianie aktywnego rekordu alfabetycznie
- 3. Jak utworzyć edytowalne zapytanie UNION?
- 4. Zapytanie SQL z UNION w Doctrine Symfony
- 5. CodeIgniter JOIN (zapytanie SELECT
- 6. Codeigniter: $ query-> free_result() przy korzystaniu z rekordu aktywnego?
- 7. CodeIgniter- aktywna wstawka rekordu, jeśli nowa lub aktualizacja duplikatu
- 8. Jak wykonać moje zapytanie SQL w CodeIgniter
- 9. CodeIgniter granica zapytanie do bazy danych
- 10. mysql zapytanie dwie tabele, UNION i gdzie klauzula
- 11. Directory.GetFiles() nie działa z wzorcem "."
- 12. Spring MockMvc przekierowywany z wzorcem
- 13. Codeigniter LIKE z wildcard (%)
- 14. Jak pobrać rekord z innej tabeli, jeśli pierwsza tabela nie zwraca rekordu przy użyciu UNION w zapytaniu MySQL
- 15. MYSQL UNION DISTINCT
- 16. Zapytanie SQL wychodzące + kodek
- 17. zapytania UNION z Propel ORM
- 18. MySQL - Korzystanie z UNION LIMIT
- 19. Różnica między wzorcem adaptera obiektu i wzorcem adaptera klasy
- 20. Yii - Pobierz min. Maks. Kolumnę przy aktywnym rekordzie
- 21. Nie znaleziono pakietów z określonym wzorcem
- 22. Używanie modelu domeny z wzorcem State State
- 23. Numeryczne pole tekstowe z wzorcem MVVM
- 24. Uzyskiwanie select2 do pracy z aktywnym adminem
- 25. Oracle: Pobranie rekordu z datą maksymalną
- 26. Wiele połączeń w Codeigniter
- 27. Pusty ekran z CodeIgniter
- 28. CodeIgniter Problem z paginacją
- 29. CodeIgniter form_radio z SET_VALUE
- 30. PayPal IPN z CodeIgniter
Aby wyjaśnić, ActiveRecord CodeIgniter obsługuje tylko funkcje SQL, które są kompatybilne ze wszystkimi obsługiwanymi typami SQL (lub implementuje je na swój własny sposób). Ideą ActiveRecord jest abstrakcja typu bazy danych, która ma być niezależna od bazy danych i pozwolić użytkownikom na przejście z MySQL na MSSQL lub cokolwiek innego bez większego problemu. Gdyby spróbowali dodać unisono, wkręciłoby się z innymi typami baz danych. –
Niezależna baza danych i niech ludzie przenoszą się z MySQL na MSSQL lub cokolwiek innego bez poważnego problemu – Louis
Nazwij jeden popularny RDBMS, który nie obsługuje UNION? Inne ORMy (semantyka ActiveRecord), takie jak SQLAlchemy, oferują doskonałe wsparcie dla UNION-ów i JOIN (różnych rodzajów) we wszystkich bazach danych, w tym SQLite. W przypadku back-endów, które nie obsługują go bezpośrednio (np. SQLite), ORM sprawia, że działa, wykonując trochę więcej zakulisów, jednocześnie zachowując przenośność. W tym konkretnym przypadku, wykonując zapytanie ręcznie, tracisz wszystkie pozory przenośności oraz bardziej zaawansowane funkcje samego systemu ActiveRecord (np. Filtrowanie tabel). – amcgregor