賞金將在 4 天后到期。此問題的答案有資格獲得 50聲望賞金。 xanabobana希望引起對這個問題的更多關注。
如何在運行查詢之前使用 get_compiled_select 或 count_all_results 而不會將表名添加兩次?當我在其中任何一個之后使用 $this->db->get('tblName') 時,我收到錯誤:
Not unique table/alias: 'tblProgram'
SELECT * FROM (`tblProgram`, `tblProgram`) JOIN `tblPlots` ON `tblPlots`.`programID`=`tblProgram`.`pkProgramID` JOIN `tblTrees` ON `tblTrees`.`treePlotID`=`tblPlots`.`id` ORDER BY `tblTrees`.`id` ASC LIMIT 2000
如果我不在 count_all_results 或 $this->db->get() 中使用表名,則會收到未使用表的錯誤。我怎樣才能讓它只設定一次表名?
public function get_download_tree_data($options=array(), $rand=""){
//join tables and order by tree id
$this->db->reset_query();
$this->db->join('tblPlots','tblPlots.programID=tblProgram.pkProgramID');
$this->db->join('tblTrees','tblTrees.treePlotID=tblPlots.id');
$this->db->order_by('tblTrees.id', 'ASC');
//get number of results to return
$allResults=$this->db->count_all_results('tblProgram', false);
//chunk data and write to CSV to avoid reaching memory limit
$offset=0;
$chunk=2000;
$treePath=$this->config->item('temp_path')."$rand/trees.csv";
$tree_handle=fopen($treePath,'a');
while (($offset<$allResults)) {
$this->db->limit($chunk, $offset);
$result=$this->db->get('tblProgram')->result_array();
foreach ($result as $row) {
fputcsv($tree_handle, $row);
}
$offset=$offset $chunk;
}
fclose($tree_handle);
return array('resultCount'=>$allResults);
}
uj5u.com熱心網友回復:
您的代碼中的缺陷是它旨在選擇一些記錄的子集及其在同一查詢中的總數。這在 MySQL 中是不可能的,因此您無法生成這樣的查詢,因此,您會收到上述錯誤。問題是,如果你做一個
select ... from t where ... limit 0, 2000
那么您將獲得最多 2000 條記錄,因此,如果符合條件的總記錄的計數大于限制,那么您將無法從上面準確獲得計數,因此,在這種情況下,您需要
select count(1) from t where ...
這意味著您需要構建您的實際查詢(您count_all_results呼叫下方的代碼),查看結果數量是否達到限制。如果結果的數量沒有達到限制,那么您不需要執行單獨的查詢來獲取計數,因為您可以計算$offset * $chunk $recordCount. 但是,如果您獲得盡可能多的記錄,那么您將需要在沒有order_by呼叫的情況下構建另一個查詢,因為計數與您的排序無關并獲取計數。
uj5u.com熱心網友回復:
要計算查詢將回傳多少行,基本上必須執行所有作業。也就是先得到計數,再執行查詢是不切實際的;你也可以只做查詢。
如果您的目標是通過獲取一些行加上總計數來“分頁”,那本質上是兩個獨立的操作(可以組合起來看起來像一個。)
如果目標是估計行數,那么SHOW TABLE STATUSor SELECT Rows FROM information_schema.TABLES WHERE ...會給你一個估計值。
如果您想查看是否有,請說“至少 100 行”,那么這可能是實用的:
SELECT 1 FROM ... WHERE ... ORDER BY ... LIMIT 99,1
看看你是否得到一排回來。但是,這可能有效也可能無效,具體取決于索引WHERE和ORDER BY. (向我們展示查詢,我可以詳細說明。)
使用OFFSET分塊是非常低效的。如果沒有可用的索引,那么它實際上是對每個塊執行整個查詢。如果有可用的索引,塊就會越來越慢。這里討論了為什么OFFSET不適合“分頁”,以及一個有效的解決方法:分頁。它討論了如何“記住你離開的地方”作為一種有效的分塊技術。每個塊獲取 100 到 1000 行。
uj5u.com熱心網友回復:
$this->db->count_all_results()
計算回傳結果的數量count_all_results()
計算回傳的結果的數量很有用——如果一段預計至少有一行的代碼被傳遞為零行,通常會出現錯誤。如果不處理零結果的可能性,應用程式可能會變得不可預測地不穩定,并且可能會向惡意用戶提供有關應用程式架構的提示。確保正確處理零結果是我們將重點關注的內容。
允許您確定特定 Active Record 查詢中的行數。查詢將接受查詢生成器限制器,例如 where()、or_where()、like()、or_like() 等。示例:
echo $this->db->count_all_results('my_table'); // Produces an integer, like 25
$this->db->like('title', 'match');
$this->db->from('my_table');
echo $this->db->count_all_results(); // Produces an integer, like 17
但是,此方法還會重置您可能已傳遞給 select() 的任何欄位值。如果需要保留它們,可以將 FALSE 作為第二個引數傳遞:
echo $this->db->count_all_results('my_table', FALSE);
get_compiled_select()
該方法$this->db->get_compiled_select();在 codeigniter v3.0 中引入,并編譯活動記錄查詢而不實際執行它。但這并不是一種全新的方法。在舊版本的 CI 中,它就像$this->db->_compile_select();,但該方法在以后的版本中受到保護,因此無法回呼。
// Note that the second parameter of the get_compiled_select method is FALSE
$sql = $this->db->select(array('field1','field2'))
->where('field3',5)
->get_compiled_select('mytable', FALSE);
// ...
// Do something crazy with the SQL code... like add it to a cron script for
// later execution or something...
// ...
$data = $this->db->get()->result_array();
// Would execute and return an array of results of the following query:
// SELECT field1, field1 from mytable where field3 = 5;
注意:-get_compiled_select()當您使用查詢生成器快取功能并且不重置查詢時,兩次呼叫將導致快取被合并兩次。反過來,如果您正在快取一個 select() - 選擇相同的欄位兩次。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/453538.html
