MYSQL:隨機抽取一條數據庫記錄


  今天我們要實現從隨機抽取一條數據庫記錄的功能,並且抽取出來的數據記錄不能重復

  1、首先我們看文章表中的數據:

  

  2、實現功能代碼如下:

  

  1   /**
  2      * 獲取隨機的N篇文篇
  3      * @param int $len 文章篇數
  4      */
  5     public static function getRandom($len = 6) {
  6         # 查詢數據庫,得到最小Id
  7         # SELECT min(id) FROM mimi_aritcle
  8         $min = Db::name(self::$tb)->field('min(id)')->select();
  9         $min = $min[0]['min(id)'];
 10 
 11         # 查詢數據庫,得到最大id
 12         # SELECT max(id) FROM mimi_article
 13         $max = Db::name(self::$tb)->field('max(id)')->select();
 14         $max = $max[0]['max(id)'];
 15 
 16         # 初始化存儲數據
 17         $result = [];
 18         # 初始化id數組
 19         $randId_arr = [];
 20 
 21         for ($i = 1; $i <= $len; $i++) {
 22             # 先設重復提取記錄為false,進入do循環
 23             $is_repeat_2 = false;
 24 
 25             # do..while,即使條件不成立,循環起碼執行一次
 26             do {
 27                 do {
 28                     # 產生一個隨機整數 
 29                     # 注意:產生的整數與數據庫無關,不要因為兩個參數是從數據庫中得到的,
 30                     #      就誤以為是在產生數據庫中的隨機id
 31                     $randId    = rand($min, $max);
 32 
 33                     # 判斷是否有重復提取的記錄
 34                     $is_repeat = in_array($randId, $randId_arr);
 35                 } while ($is_repeat);
 36 
 37                 if($is_repeat_2){
 38                     # 將提取出的不同id進行入棧
 39                     array_push($randId_arr, $row[0]['id']);
 40                 }
 41 
 42                 # 抽取一條數據庫記錄
 43                 /**
 44                  * 首先,我們要記住:
 45                  * 步驟一表圖中查詢數據庫,獲取到最小id是1, 最大id是50,就能知道數據庫中一定有id=1和id=50的記錄  46                  * 所以,
 47                  * 1、這里使用id>$randId而不是id=$randId,是防止數據庫中的某條記錄被刪除,導致找不到數據庫中對應的id記錄;  48                  * 例子:
 49                  * (1) 如果隨機抽取的$randId為6,那么使用條件id>$randId-1的話,就會讀取到數據庫中所有id>5的記錄;
 50                  *     從數據庫截圖中,我們可以看到,能夠讀取到數據庫id=10、20、30、40、50的記錄
 51                  * (2) 如果我們使用id=$randId,隨機抽取的$randId為6,那么使用功能id=$randId的話,就會讀取到數據庫中id=6的固定記錄,
 52                  *     但是數據庫中沒有id=6的記錄,就會發生錯誤
 53                  * 
 54                  * 2、這里使用id>$randId-1而不是id>$randId,是為了防止我們隨機抽取的數為最大數50的時候,條件不成立,  55                  *    從而導致報錯,因為id=50是數據庫中最大數了  56                  * 例如:
 57                  * (1) 如果隨機抽取的$randId為最大數50,那么使用條件id>$randId-1的話,就會讀取到數據庫中所有id>49的記錄,
 58                  *     由於符合id>49條件的只有id=50的記錄,那么就能保證,我有數據可以提取到;
 59                  * (2) 如果隨機抽取的$randId為最大數50,那么使用條件id>$randId的話,就會讀取到數據庫中所有id>50的記錄,
 60                  *     但是數據庫中沒有符合條件的數據,就會發生錯誤
 61                  * (3) 如果隨機抽取的$randId為最小數1,使用條件 id>$randId 的話,id = 1 的記錄永遠也不能被隨機選中
 62                  * 
 63                  * 3、這里使用order('id ASC')而不是order('id DESC')原因:當我們獲取到數據后,要獲取最接近$randId的值  64                  * (1) 如果隨機抽取的$randId為6,我們就能從所有id>5的記錄,即id=10、20、30、40、50
 65                  *     的記錄,這時候的結果是循環6次后的總體列表,那我們需要最靠近6的記錄,就需要使用order('id ASC')
 66                  *     進行升序排列,這時候,列表中的第一個數據就是id=10的,就是我們想要的記錄
 67                  * (2) 如果隨機抽取的$randId為6,我們就能從所有id>5的記錄,即id=10、20、30、40、50
 68                  *     的記錄,如果使用order('id DESC'),那么我們得到的數據永遠是最不靠近6的記錄,即id=50的記錄
 69                  * (3) 不使用order,有時候會排列不一樣,(通常在數據記錄不同時才會發現到)
 70                  * 
 71                  * 4、這里使用limit原因:因為我們需要的是一條記錄,而不是一個列表,所以,我們只需要提取符合條件的第一條記錄即可  72                  * 例子:
 73                  * (1) 如果隨機抽取的$randId為6,那么使用條件id>$randId-1的話,就會讀取到數據庫中所有id>5的記錄而不是固定一條記錄;
 74                  *     從數據庫截圖中,我們可以看到,能夠讀取到數據庫id=10、20、30、40、50的記錄,但是我們循環一次只需要一條記錄,那么
 75                  *     只需要提取第一條符合的記錄,就是id=10的記錄
 76                  * (2) 如果我們不使用limit的話,那么系統就會把所有符合條件的記錄都提取出來
 77                  * 
 78                 */
 79                 $row = Db::name(self::$tb)
 80                     ->field('id, title, href')
 81                     ->where(['id' => ['>', $randId - 1]])
 82                     ->order('id ASC')
 83                     ->limit(0, 1)
 84                     ->select();     
 85                 
 86                 # 判斷是否有重復提取的數據庫記錄
 87                 $is_repeat_2 = in_array($row[0]['id'], $randId_arr);
 88             } while ($is_repeat_2);
 89 
 90 
 91             # 將提取出來的數據庫id進行入棧
 92             array_push($randId_arr, $row[0]['id']);
 93 
 94             if(empty($row)){
 95                return false;
 96             }
 97         
 98             # 將提取出的所有最終數據庫數據入棧
 99             array_push($result, $row[0]);
100         }
101 
102         return $result;
103     }

 

 

  

  

 

  以上

  加油ヾ(◍°∇°◍)ノ゙


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM