在ThinkPHP中使用 BETWEEN AND 注意项

本文探讨了在使用BETWEENAND进行价格区间筛选时遇到的问题,发现其在处理varchar字段类型时查询结果不准确,而处理int类型时则正常。文章旨在寻找解决varchar字段类型下BETWEENAND查询问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近写一个价格区间的筛选,用到BETWEEN AND

最近写一个价格区间的筛选,用到BETWEEN AND,当数据库查询的字段为varchar字段类型时,查询的数据不对,当为int类型时查询的数据时对的。

我得出的结论是 BETWEEN AND 查询的字段为Int型,是这样吗,求大家支招!

在这里插入图片描述在这里插入图片描述

/** * @notes 京东仓储服务费核对逻辑 * @param $yearMonth * @return bool * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException * @author 胡军 * @date 2025/06/27 */ public function wareHousingFeeVerifyDo($yearMonth):bool{ $monthTimeRange = $this->getMonthTimeRange($yearMonth); //获取时间范围内的数据并进行分组统计 //total_quantity 总数 //total_settlement_amount 总的结算金额 $itemizationMonthList = WareHousingFeesItemizationModel::whereBetween('business_time', [$monthTimeRange['startTime'], $monthTimeRange['endTime']]) ->field([ 'document_number', 'document_type', 'SUM(quantity) as total_quantity', 'SUM(settlement_amount) as total_settlement_amount' ]) ->group('document_number, document_type') ->select() ->toArray(); //一次性读取报价单避免foreach循环 提升效率 $quoteList = WareHousingFeesQuoteModel::select()->toArray(); $quoteListRst = []; foreach ($quoteList as $item) { $quoteListRst[$item['service_type']] = $item; } if(!empty($quoteListRst)){ foreach($itemizationMonthList as $key => $value){ //初始化理论金额为0 $itemizationMonthList[$key]['theoretical_amount'] = 0; if($value['document_type'] == '出库单' && !empty($quoteListRst['出库单'])){ //$value['total_quantity'] 数量 if($value['total_quantity'] <= 3){ //理论金额 $itemizationMonthList[$key]['theoretical_amount'] = $quoteListRst['出库单']['first_three_items']; } else { $itemizationMonthList[$key]['theoretical_amount'] = $quoteListRst['出库单']['first_three_items'] + ($value['total_quantity'] - 3) * $quoteListRst['出库单']['additional_items']; } } if($value['document_type'] == '退供单' && !empty($quoteListRst['退供单'])){ $itemizationMonthList[$key]['theoretical_amount'] = $quoteListRst['退供单']['first_three_items'] * $value['total_quantity']; } if($value['document_type'] == '退货单' && !empty($quoteListRst['退货单'])){ if($value['total_quantity'] <= 3){ $itemizationMonthList[$key]['theoretical_amount'] = $quoteListRst['退货单']['first_three_items']; } else { $itemizationMonthList[$key]['theoretical_amount'] = $quoteListRst['退货单']['first_three_items'] + ($value['total_quantity'] - 3) * $quoteListRst['退货单']['additional_items']; } } //正常计算出来的理论金额不应该是0 那么这个时候就要记录日志便于排查 if($itemizationMonthList[$key]['theoretical_amount'] == 0){ //echo $value['document_number'].PHP_EOL; Log::warning('【京东仓储服务费明细核对】--月份为:'.$yearMonth."的京东仓储服务费订单明细核对匹配不到京东仓储服务费报价表la_storage_service_quotes当中的类型,明细单据编号为".$value['document_number']); unset($itemizationMonthList[$key]); continue; }else{ //差异:结算金额-理论金额 $itemizationMonthList[$key]['balance'] = $value['total_settlement_amount'] - $itemizationMonthList[$key]['theoretical_amount']; } } //批量分批次更新数据库 $status = true; $batchSize = 50; // 每批10条记录 $totalCount = count($itemizationMonthList); $batchCount = ceil($totalCount / $batchSize); $itemizationModel = new WareHousingFeesItemVeryModel(); for ($i = 0; $i < $batchCount; $i++) { $batchData = array_slice($itemizationMonthList, $i * $batchSize, $batchSize); $documentNumbers = array_column($batchData, 'document_number'); // 提取当前批次的所有单据号 try { $itemizationModel->startTrans(); // 批量删除操作(根据单据号) if (!empty($documentNumbers)) { $itemizationModel->whereIn('document_number', $documentNumbers)->delete(); } // 使用批量更新替代循环单条更新 $itemizationModel->saveAll($batchData); $itemizationModel->commit(); } catch (\Exception $e) { $itemizationModel->rollback(); //记录日志 Log::error('【京东仓储服务费明细核对异常】--月份为:'.$yearMonth."的费用核对发生错误:" . $e->getMessage()); //其中一个批次数据处理失败则直接退出循环 不再继续执行后续批次的数据处理 报错给前端显示 $status = false; break; } } return $status; }else{ return false; } } /** * @notes 根据年月比如2025-05获取当月时间范围 精确到秒 (git有问题未解决 暂时无法写入common.php当中 临时放这) * @param string $yearMonth * @return array * @author 胡军 * @date 2025/06/27 */ private function getMonthTimeRange(string $yearMonth): array { // 验证输入格式 (YYYY-MM) if (!preg_match('/^\d{4}-(0[1-9]|1[0-2])$/', $yearMonth)) { throw new InvalidArgumentException('输入格式不正确,必须为YYYY-MM格式'); } list($year, $month) = explode('-', $yearMonth); // 构建开始时间 $startTime = "{$year}-{$month}-01 00:00:00"; // 使用DateTime类计算当月最后一天 $lastDay = (new \DateTime("{$year}-{$month}-01")) ->modify('last day of this month') ->format('d'); // 构建结束时间 $endTime = "{$year}-{$month}-{$lastDay} 23:59:59"; return [ 'startTime' => $startTime, 'endTime' => $endTime ]; } 我需要通过上面的代码去处理了数据库100万的数据进行费用核对,但是我感觉性能肯定是受影响的,请根据我的代码业务逻辑不变的前提下,去优化一下代码 ,提升整体性能
最新发布
07-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值