php 循环里面套sql怎么解决

功能要求: 企业列表(展示企业的基本信息,这里只获取了名称、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处理数组、数据的能了肯定比你查询数据库厉害

原文地址:https://www.cnblogs.com/hinq/p/13608072.html