php 循环里面套sql怎么解决
功能要求: 企业列表(展示企业的基本信息,这里只获取了名称、logo、和服务类型), 服务类型说明: 服务类型一共3级,1、2级是必填的,3级是非必填,如果填的话最多3个, 服务类型1、2、3保存在一张表, pid作为关联字段(默认为0) 企业列表数据结构 服务类型1、2级都是唯一的所有查询企业数据时就关联获取到了
array:4 [
0 => array:6 [
"id" => 1
"company_name" => "公司名称1"
"logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
"service_type1" => array:2 [
"id" => 101
"name" => "金融服务"
]
"service_type2" => array:2 [
"id" => 102
"name" => "理财"
]
"service_type3" => "826,827,828"
]
1 => array:6 [
"id" => 2
"company_name" => "公司名称2"
"logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
"service_type1" => 0
"service_type2" => 0
"service_type3" => 0
]
2 => array:6 [
"id" => 3
"company_name" => "公司名称3"
"logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
"service_type1" => array:2 [
"id" => 13
"name" => "日用百货"
]
"service_type2" => array:2 [
"id" => 15
"name" => "文具"
]
"service_type3" => "291,292,295"
]
3 => array:6 [
"id" => 4
"company_name" => "公司名称4"
"logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
"service_type1" => array:2 [
"id" => 48
"name" => "信息服务"
]
"service_type2" => array:2 [
"id" => 50
"name" => "操作系统"
]
"service_type3" => "523,524,526"
]
]
问题就是第三级是用逗号隔开保留的数据,关联查不好查,所以需要单独的处理第三级的数据,怎么弄?
//我这里用的是laravel框架,数据库的交互都是封装好的 下面是根据封装的方法处理的查询数据
foreach( $data as $key => &$vo ){
//首先将第三级的数据整理成一个一维数组
$service_type3 = explode( ',' , $vo['service_type3'] );
$arr_option3['whereIn'] = ['id' => $service_type3]; //whereIn查询指定的数据
$arr_option3['field'] = ['id','name']; //只获取指定的字段信息
$vo['service_type3'] = CompanyServiceTypeRepository::getAll( $arr_option3 ); //查询数据
}
这是执行上面代码数据的结果
array:4 [
0 => array:6 [
"id" => 1
"company_name" => "公司名称1"
"logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
"service_type1" => array:2 [
"id" => 101
"name" => "金融服务"
]
"service_type2" => array:2 [
"id" => 102
"name" => "理财"
]
"service_type3" => array:3 [
0 => "外汇"
1 => "基金"
2 => "股票"
]
]
1 => array:6 [
"id" => 2
"company_name" => "公司名称2"
"logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
"service_type1" => 0
"service_type2" => 0
"service_type3" => []
]
2 => array:6 [
"id" => 3
"company_name" => "公司名称3"
"logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
"service_type1" => array:2 [
"id" => 13
"name" => "日用百货"
]
"service_type2" => array:2 [
"id" => 15
"name" => "文具"
]
"service_type3" => array:3 [
0 => "桌面用品"
1 => "办公本薄"
2 => "文件装整"
]
]
3 => & array:6 [
"id" => 4
"company_name" => "公司名称4"
"logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
"service_type1" => array:2 [
"id" => 48
"name" => "信息服务"
]
"service_type2" => array:2 [
"id" => 50
"name" => "操作系统"
]
"service_type3" => array:3 [
0 => "虚拟机系统"
1 => "Unix/Linux"
2 => "Windows/dos"
]
]
]
数据结果正确? 是的正确的 也是我想要的数据机构。 但是当时没有考虑明白, 现在只有4条数据,那么就要循环4次去获取第三级分类名称,要是数据是10条?20条? all? 那不就给数据库增加压力了吗,而且如果有好几家公司的第三级数据相同的话,是不是重复执行了相同的sql语句? 这一层面上是不是又造成了资源浪费。
所有称同事没有注意到我个代码 , 立马 马不停蹄的赶紧改掉,怎么改? 先提供一个思路吧在贴代码
我们一点要避免循环里面套sql查询, 这个你会有意想不到的结果。所有我的思路是将所有企业的第三级数据整理成一个数组,统一去查出所有的第三级名称,在循环数组将对应的名称保存到对应的企业下保存起来。
下面我来贴出代码,虽然代码量会比上面foreach查询的量多一些,但是效率和资源浪费上面提升了很多。
使用到的相关php函数,基本上都是常用函数(具体函数说明请自行百度): array_column() 、implode()、explode()、array_values()、asort()、array_unique()、array_shift()
$service_type3 = array_column( $data , 'service_type3'); //这里会得到一个一维数组,元素是上面$data数据的service_type3字段数据
$service_type3 = implode( ',' , $service_type3 ); //将数据切割成字符串 得到的结果是 "826,827,828,0,291,292,295,523,524,526"
$service_type3 = explode(',', $service_type3 ); //再次将上面的字符串切割成数组(很有必要) 得到的又是一个一维数组,和第一步的数据是不一样的
$service_type3 = array_unique( $service_type3 ); //数组去重
//第一种方法 尽可能的使用php定义的函数
asort( $service_type3 ); //将数组内的元素由低到高进行一下排序(也很有必要,因为又可以会有0在里面,由于上面去重了一次,所有经过排序后如果有0元素的话会在第一位)
$service_type3 = array_values( $service_type3 ); //重新定义数组的索引
if( $service_type3[0] == 0 ){ //如果数组的第一个元素是0
array_shift( $service_type3 ); //删除第一个元素
}
//第二种方法
// foreach ( $service_type3 as $key => $vo ){
// if( $vo == 0 ){
// unset( $service_type3[$key] );
// }
// }
最终得到的数据
array:8 [
0 => "826"
1 => "827"
2 => "828"
4 => "291"
5 => "292"
6 => "295"
7 => "523"
8 => "524"
]
接下来我们在查询第三级的类型名称 这里就只用查询一次数据库就能查出所有的第三级类型名称数据了
$arr_option3['whereIn'] = ['id' => $service_type3]; //所有3级的id
$arr_option3['field'] = ['id','name'];
$arr_service_type3 = CompanyServiceTypeRepository::getAll( $arr_option3 ); //获取第三级服务类型名称
$arr_service_type3 = array_column( $arr_service_type3 ,'name' ,'id'); //将数据整理成id为键 name为值的一维键值对数组
得打的结果
array:8 [
828 => "外汇"
827 => "基金"
826 => "股票"
524 => "Unix/Linux"
523 => "Windows/dos"
295 => "桌面用品"
292 => "办公本薄"
291 => "文件装整"
]
最后将数据保存到对应的企业列表中, 可以对比一下与上面循环里面套sql得到的结果是否一样
foreach ( $data as $key => &$vo ){
if( $vo['service_type3'] != 0 ){
$service_type3 = explode( ',' , $vo['service_type3']); //将字符串切割成数组
$vo['service_type3'] = [];
foreach ( $service_type3 as $k => $v ){
$vo['service_type3'][] = $arr_service_type3[$v];
}
}else{
$vo['service_type3'] = [];
}
11 }
最终得到的结果
array:4 [
0 => array:6 [
"id" => 1
"company_name" => "公司名称1"
"logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
"service_type1" => array:2 [
"id" => 101
"name" => "金融服务"
]
"service_type2" => array:2 [
"id" => 102
"name" => "理财"
]
"service_type3" => array:3 [
0 => "股票"
1 => "基金"
2 => "外汇"
]
]
1 => array:6 [
"id" => 2
"company_name" => "公司名称2"
"logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
"service_type1" => 0
"service_type2" => 0
"service_type3" => []
]
2 => array:6 [
"id" => 3
"company_name" => "公司名称3"
"logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
"service_type1" => array:2 [
"id" => 13
"name" => "日用百货"
]
"service_type2" => array:2 [
"id" => 15
"name" => "文具"
]
"service_type3" => array:3 [
0 => "文件装整"
1 => "办公本薄"
2 => "桌面用品"
]
]
3 => & array:6 [
"id" => 4
"company_name" => "公司名称4"
"logo" => "men_hu/picture/2020-07/5f07e6df5561f.jpg"
"service_type1" => array:2 [
"id" => 48
"name" => "信息服务"
]
"service_type2" => array:2 [
"id" => 50
"name" => "操作系统"
]
"service_type3" => array:3 [
0 => "Windows/dos"
1 => "Unix/Linux"
2 => "Unix/Linux"
]
]
]
还是那句话 尽量不要在循环里面套sql语句, 我这里应该第三级的数据不是固定的可以无限的添加,所以才整理成数组用whereIn查询了一次, 但是如果服务类型个数有限(100个以内的话), 直接全部多出来,在出来数组(这里我就不仔细说了 懂的自然懂)
说白了就是php处理数组、数据的能了肯定比你查询数据库厉害
php 循环里面套sql怎么解决的更多相关文章
- handlebars,each循环里面套each循环
handlebars可以用each自动进行循环,下面介绍一下each循环里面套循环来着. html代码 !DOCTYPE html> <html> <head> < ...
- uni-app如何解决在for循环里调用异步请求获取数据顺序混乱问题?
总结/朱季谦 先前有一次做uni-app的js接口对接时,遇到过这样的情况,在for循环里,调用一个异步请求时,返回来的值顺序是乱的,因此,在以下的代码里,push到数组里的值,每次的顺序可能都是不一 ...
- 关于hasNextInt判断后无限循环输出else项的解决办法
话不多说,上来就是干! import java.util.Scanner; public class Test_hasNextInt { /** * @param args */ public sta ...
- sql server 小技巧(8) visual studio 2013里使用Sql server compact 4.0及发布问题处理
1. 安装 Microsoft SQL Server Compact 4.0 https://www.microsoft.com/zh-cn/download/confirmation.aspx?i ...
- 【vue】vue使用Element组件时v-for循环里的表单项验证方法
转载至:https://www.jb51.net/article/142750.htm标题描述看起来有些复杂,有vue,Element,又有表单验证,还有v-for循环?是不是有点乱?不过我相信开发中 ...
- js循环里进行回调,引用循环里的变量,发现只是最后值的问题
做项目的时候,栽在一个小地方,是这样的 我有很多个坐标点,我想把这些坐标点都绑定一个事件,当点击了这个坐标点之后,发送一个ajax 请求,将坐标点的id 发出去,等待显示返回的数据 但是实际当中,无论 ...
- Java问题记录——循环里的二次判断与状态更新
Java问题记录——循环里的二次判断与状态更新 摘要:本文主要记录了在循环操作时可能出现的问题. 问题重现 在使用循环结构时,如果使用了定时任务,或者代码会多次调用循环结构,可能会导致有些对象会被循环 ...
- SQL Server解决孤立用户浅析
孤立用户概念 所谓孤立用户即指在服务器实例上未定义或错误定义了其相应 SQL Server 登录名的数据库用户无法登录到实例. 这样的用户被称为此服务器实例上的数据库的"孤立用 ...
- [经验] 新版SkyIAR、Easy Image X在有些PE里不能运行的解决办法
[经验] 新版SkyIAR.Easy Image X在有些PE里不能运行的解决办法 xxwl2008 发表于 2013-1-26 11:58:38 https://www.itsk.com/threa ...
随机推荐
- vue-cli脚手架的搭建
1.安装node.js 2.安装cnpm npm install -g cnpm --registry=https://registry.npm.taobao.org 3.安装vue-cli npm ...
- 极简 Node.js 入门 - Node.js 是什么、性能有优势?
极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...
- 文件权限和访问控制列表ACL (1)
背景知识: 文件的权限主要针对三类对象进行定义 Owner: 属主u Group: 属组g Other: 其他o 每个文件针对每一类的访问者都设定了三种权限 r: Readable 读 w: Writ ...
- JS中escape()、encodeURI()、encodeURIComponent()区别详解
avaScript中有三个可以对字符串编码的函数,分别是: escape,encodeURI,encodeURIComponent,相应3个解码函数:unescape,decodeURI,decode ...
- CentOS7安装Redis的两种方式
1. 源码安装方式(不推荐): https://www.cnblogs.com/zuidongfeng/p/8032505.html https://www.cnblogs.com/zerotomax ...
- spring boot中使用mybatis的注意点!!!
1 生成的mapper接口上打上注解 2 在pom.xml中需要导入mysql(根据需要),jdbc和mybatis的依赖 3 在主类上设置扫描 4 com.mysql.cj.exceptions等报 ...
- 5、Java 修饰符
引言:Java的修饰符根据修饰的对象不同,分为类修饰符.方法修饰符.变量修饰符,其中每种修饰符又分为访问控制修饰符和非访问控制修饰符. 1.访问控制修饰符的总结 四个关键字:public.protec ...
- C++/C socket编程
目录 socket()函数 何为socket Internet套接字 流格式套接字SOCK_STREAM 数据报格式套接字SOCK_DGRAM TCP/IP协议族 创建套接字 加载套接字库 Windo ...
- JavaScript Babel说明
babel插件只是去唤醒 @babel/core中的转换过程 转换模块需要手动安装 npm install @babel/core 转换方式需要安装 @babel/preset-env babel默认 ...
- 震惊!ConcurrentHashMap里面也有死循环,作者留的“彩蛋”?
JDK BUG 这篇文章,聊一下我最近才知道的一个关于 JDK 8 的 BUG 吧. 首先说一下我是怎么发现这个 BUG 的呢? 大家都知道我对 Dubbo 有一定的关注,前段时间 Dubbo 2.7 ...