php 迴圈裡面套sql怎麼解決

紅色的黑發表於2020-09-03
功能要求: 企業列表(展示企業的基本資訊,這裡只獲取了名稱、logo、和服務型別), 服務型別說明: 服務型別一共3級,1、2級是必填的,3級是非必填,如果填的話最多3個,  服務型別1、2、3儲存在一張表, pid作為關聯欄位(預設為0)

企業列表資料結構 服務型別1、2級都是唯一的所有查詢企業資料時就關聯獲取到了
 1 array:4 [
 2   0 => array:6 [
 3     "id" => 1
 4     "company_name" => "公司名稱1"
 5     "logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
 6     "service_type1" => array:2 [
 7       "id" => 101
 8       "name" => "金融服務"
 9     ]
10     "service_type2" => array:2 [
11       "id" => 102
12       "name" => "理財"
13     ]
14     "service_type3" => "826,827,828"
15   ]
16   1 => array:6 [
17     "id" => 2
18     "company_name" => "公司名稱2"
19     "logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
20     "service_type1" => 0
21     "service_type2" => 0
22     "service_type3" => 0
23   ]
24   2 => array:6 [
25     "id" => 3
26     "company_name" => "公司名稱3"
27     "logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
28     "service_type1" => array:2 [
29       "id" => 13
30       "name" => "日用百貨"
31     ]
32     "service_type2" => array:2 [
33       "id" => 15
34       "name" => "文具"
35     ]
36     "service_type3" => "291,292,295"
37   ]
38   3 => array:6 [
39     "id" => 4
40     "company_name" => "公司名稱4"
41     "logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
42     "service_type1" => array:2 [
43       "id" => 48
44       "name" => "資訊服務"
45     ]
46     "service_type2" => array:2 [
47       "id" => 50
48       "name" => "作業系統"
49     ]
50     "service_type3" => "523,524,526"
51   ]
52 ]

 

問題就是第三級是用逗號隔開保留的資料,關聯查不好查,所以需要單獨的處理第三級的資料,怎麼弄? 

1 //我這裡用的是laravel框架,資料庫的互動都是封裝好的  下面是根據封裝的方法處理的查詢資料
2 foreach( $data as $key => &$vo ){
3    //首先將第三級的資料整理成一個一維陣列
4    $service_type3 = explode( ',' , $vo['service_type3'] );
5    $arr_option3['whereIn'] =  ['id' => $service_type3];     //whereIn查詢指定的資料
6    $arr_option3['field'] = ['id','name'];       //只獲取指定的欄位資訊
7    $vo['service_type3'] = CompanyServiceTypeRepository::getAll( $arr_option3 );   //查詢資料
8}

 

這是執行上面程式碼資料的結果

 1 array:4 [
 2   0 => array:6 [
 3     "id" => 1
 4     "company_name" => "公司名稱1"
 5     "logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
 6     "service_type1" => array:2 [
 7       "id" => 101
 8       "name" => "金融服務"
 9     ]
10     "service_type2" => array:2 [
11       "id" => 102
12       "name" => "理財"
13     ]
14     "service_type3" => array:3 [
15       0 => "外匯"
16       1 => "基金"
17       2 => "股票"
18     ]
19   ]
20   1 => array:6 [
21     "id" => 2
22     "company_name" => "公司名稱2"
23     "logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
24     "service_type1" => 0
25     "service_type2" => 0
26     "service_type3" => []
27   ]
28   2 => array:6 [
29     "id" => 3
30     "company_name" => "公司名稱3"
31     "logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
32     "service_type1" => array:2 [
33       "id" => 13
34       "name" => "日用百貨"
35     ]
36     "service_type2" => array:2 [
37       "id" => 15
38       "name" => "文具"
39     ]
40     "service_type3" => array:3 [
41       0 => "桌面用品"
42       1 => "辦公本薄"
43       2 => "檔案裝整"
44     ]
45   ]
46   3 => & array:6 [
47     "id" => 4
48     "company_name" => "公司名稱4"
49     "logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
50     "service_type1" => array:2 [
51       "id" => 48
52       "name" => "資訊服務"
53     ]
54     "service_type2" => array:2 [
55       "id" => 50
56       "name" => "作業系統"
57     ]
58     "service_type3" => array:3 [
59       0 => "虛擬機器系統"
60       1 => "Unix/Linux"
61       2 => "Windows/dos"
62     ]
63   ]
64 ]

 

資料結果正確?  是的正確的  也是我想要的資料機構。  但是當時沒有考慮明白,  現在只有4條資料,那麼就要迴圈4次去獲取第三級分類名稱,要是資料是10條?20條? all?  那不就給資料庫增加壓力了嗎,而且如果有好幾家公司的第三級資料相同的話,是不是重複執行了相同的sql語句? 這一層面上是不是又造成了資源浪費。

所有稱同事沒有注意到我個程式碼 , 立馬 馬不停蹄的趕緊改掉,怎麼改?   先提供一個思路吧在貼程式碼

我們一點要避免迴圈裡面套sql查詢, 這個你會有意想不到的結果。所有我的思路是將所有企業的第三級資料整理成一個陣列,統一去查出所有的第三級名稱,在迴圈陣列將對應的名稱儲存到對應的企業下儲存起來。

下面我來貼出程式碼,雖然程式碼量會比上面foreach查詢的量多一些,但是效率和資源浪費上面提升了很多。

使用到的相關php函式,基本上都是常用函式(具體函式說明請自行百度): array_column() 、implode()、explode()、array_values()、asort()、array_unique()、array_shift()

 1 $service_type3 = array_column( $data , 'service_type3');  //這裡會得到一個一維陣列,元素是上面$data資料的service_type3欄位資料
 2         $service_type3 = implode( ',' , $service_type3 );       //將資料切割成字串  得到的結果是 "826,827,828,0,291,292,295,523,524,526"
 3         $service_type3 = explode(',', $service_type3 );     //再次將上面的字串切割成陣列(很有必要)    得到的又是一個一維陣列,和第一步的資料是不一樣的
 4         $service_type3 = array_unique( $service_type3 );            //陣列去重
 5         //第一種方法  儘可能的使用php定義的函式
 6         asort( $service_type3 );   //將陣列內的元素由低到高進行一下排序(也很有必要,因為又可以會有0在裡面,由於上面去重了一次,所有經過排序後如果有0元素的話會在第一位)
 7         $service_type3 = array_values( $service_type3 );   //重新定義陣列的索引
 8         if( $service_type3[0] == 0 ){     //如果陣列的第一個元素是0
 9             array_shift( $service_type3 );  //刪除第一個元素
10         }
11         //第二種方法
12 //        foreach ( $service_type3 as $key => $vo ){
13 //            if( $vo == 0 ){
14 //                unset( $service_type3[$key] );
15 //            }
16 //        }

最終得到的資料

 1 array:8 [
 2   0 => "826"
 3   1 => "827"
 4   2 => "828"
 5   4 => "291"
 6   5 => "292"
 7   6 => "295"
 8   7 => "523"
 9   8 => "524"
10 ]

 

接下來我們在查詢第三級的型別名稱   這裡就只用查詢一次資料庫就能查出所有的第三級型別名稱資料了

1 $arr_option3['whereIn'] = ['id' => $service_type3];     //所有3級的id
2 $arr_option3['field'] = ['id','name'];
3 $arr_service_type3 = CompanyServiceTypeRepository::getAll( $arr_option3 );     //獲取第三級服務型別名稱
4 $arr_service_type3 = array_column( $arr_service_type3 ,'name' ,'id');       //將資料整理成id為鍵 name為值的一維鍵值對陣列

得打的結果

 1 array:8 [
 2   828 => "外匯"
 3   827 => "基金"
 4   826 => "股票"
 5   524 => "Unix/Linux"
 6   523 => "Windows/dos"
 7   295 => "桌面用品"
 8   292 => "辦公本薄"
 9   291 => "檔案裝整"
10 ]

最後將資料儲存到對應的企業列表中, 可以對比一下與上面迴圈裡面套sql得到的結果是否一樣

 1 foreach ( $data as $key => &$vo ){
 2    if( $vo['service_type3'] != 0  ){
 3       $service_type3 = explode( ',' , $vo['service_type3']);  //將字串切割成陣列
 4       $vo['service_type3'] = [];
 5       foreach ( $service_type3 as $k => $v ){
 6          $vo['service_type3'][] = $arr_service_type3[$v];
 7       }
 8    }else{
 9       $vo['service_type3'] = [];
10    }
11 }

最終得到的結果

 1 array:4 [
 2   0 => array:6 [
 3     "id" => 1
 4     "company_name" => "公司名稱1"
 5     "logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
 6     "service_type1" => array:2 [
 7       "id" => 101
 8       "name" => "金融服務"
 9     ]
10     "service_type2" => array:2 [
11       "id" => 102
12       "name" => "理財"
13     ]
14     "service_type3" => array:3 [
15       0 => "股票"
16       1 => "基金"
17       2 => "外匯"
18     ]
19   ]
20   1 => array:6 [
21     "id" => 2
22     "company_name" => "公司名稱2"
23     "logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
24     "service_type1" => 0
25     "service_type2" => 0
26     "service_type3" => []
27   ]
28   2 => array:6 [
29     "id" => 3
30     "company_name" => "公司名稱3"
31     "logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
32     "service_type1" => array:2 [
33       "id" => 13
34       "name" => "日用百貨"
35     ]
36     "service_type2" => array:2 [
37       "id" => 15
38       "name" => "文具"
39     ]
40     "service_type3" => array:3 [
41       0 => "檔案裝整"
42       1 => "辦公本薄"
43       2 => "桌面用品"
44     ]
45   ]
46   3 => & array:6 [
47     "id" => 4
48     "company_name" => "公司名稱4"
49     "logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
50     "service_type1" => array:2 [
51       "id" => 48
52       "name" => "資訊服務"
53     ]
54     "service_type2" => array:2 [
55       "id" => 50
56       "name" => "作業系統"
57     ]
58     "service_type3" => array:3 [
59       0 => "Windows/dos"
60       1 => "Unix/Linux"
61       2 => "Unix/Linux"
62     ]
63   ]
64 ]

 

還是那句話  儘量不要在迴圈裡面套sql語句, 我這裡應該第三級的資料不是固定的可以無限的新增,所以才整理成陣列用whereIn查詢了一次, 但是如果服務型別個數有限(100個以內的話), 直接全部多出來,在出來陣列(這裡我就不仔細說了 懂的自然懂)

說白了就是php處理陣列、資料的能了肯定比你查詢資料庫厲害

 

相關文章