金额合计求值(返回总计值为指定数的集合)

本文介绍了一个SQL查询函数,用于在数据库表中查找单独或组合记录的金额是否与给定的目标金额相等。通过递归查询的方式实现了金额的精确匹配。

表test中记录:
  aa     bb 
  001   50.5
  002   60
  003   15.4
  004   25
  005   48
  ...

输入任一金额,然后在表中查找是否有该金额或几条记录的合计等于该金额.
如:输入25,则要找出004,输入85,则要找出002与004,依次类推。
------------------------------------------------------------------------------------


--测试数据
create table test(aa varchar(10),bb numeric(10,2))
insert test select '001',50.5
union  all  select '002',60
union  all  select '003',15.4
union  all  select '004',25
union  all  select '005',48
union  all  select '006',37
go

--查询函数
create function fn_search(@Num numeric(10,2))
returns @r table (aa varchar(10),bb numeric(10,2))
as
begin
 declare @t table (aa varchar(8000),aa1 varchar(10),bb numeric(10,2),level int)
 declare @l int

 insert @r select aa,bb from test where bb=@num
 if @@rowcount>0 goto lb_exit

 set @l=0
 insert @t select ','+aa+',',aa,bb,@l from test where bb<@num
 while @@rowcount>0
 begin
  insert @r select distinct a.aa,a.bb
  from test a,(
   select a.aa,a.bb,aa1=b.aa from test a,@t b
   where b.level=@l
    and b.aa1<a.aa
    and a.bb=@num-b.bb
  )b where a.aa=b.aa or charindex(','+a.aa+',',b.aa1)>0
  if @@rowcount>0 goto lb_exit

  set @l=@l+1
  insert @t select b.aa+a.aa+',',a.aa,a.bb+b.bb,@l
  from test a,@t b
  where b.level=@l-1
   and b.aa1<a.aa
   and a.bb<@num-b.bb
 end

lb_exit:
 return
end
go

--调用测试1
select * from dbo.fn_search(25)

/*--结果

aa         bb          
---------- ------------
004        25.00

(所影响的行数为 1 行)
--*/

--调用测试2
select * from dbo.fn_search(135.5)

/*--结果

aa         bb          
---------- ------------
001        50.50
002        60.00
004        25.00
005        48.00
006        37.00

(所影响的行数为 5 行)
--*/

--调用测试3(找不到的,无返回值)
select * from dbo.fn_search(135.7)

/*--结果
aa         bb          
---------- ------------

(所影响的行数为 0 行)
--*/
go

drop table test
drop function fn_search

 

本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/zjcxc/archive/2004/08/06/67518.aspx

Map<String, Object> map = new HashMap<>(); //核销订单 List<ExaminationOrderStatisticsVO> examinationOrderList = new ArrayList<>(); //对比核销 List<ExaminationOrderStatisticsVO> examinationOrderListComparison = new ArrayList<>(); //分区列 List<Area> areaByParentIdList = new ArrayList<>(); //医院列 List<HospitalInfo> hospitalInfos = new ArrayList<>(); List<SysDictData> sourceDictData = new ArrayList<>(); if (StringUtils.isNotEmpty(dto.getZoneType())) { OrderAreaDTO orderPageDTO = new OrderAreaDTO(); // 获取医院列 if (SysDictTypeConstant.PLATFORM_TYPE.equals(dto.getZoneType())) { sourceDictData = sysDictDataMapper.selectDictDataByType(SysDictTypeConstant.PLATFORM_TYPE); List<String> soureList = sourceDictData.stream().map(SysDictData::getDictValue).collect(Collectors.toList()); hospitalInfos = hospitalInfoMapper.selectNormalHospitalByDictValues("platform_type", soureList); orderPageDTO.setHospitalIds(hospitalInfos.stream().map(HospitalInfo::getId).collect(Collectors.toList())); } else if ("hospital_level".equals(dto.getZoneType())) { orderPageDTO.setHospitalIds(hospitalInfos.stream().map(HospitalInfo::getId).collect(Collectors.toList())); sourceDictData = sysDictDataMapper.selectDictDataByType("hospital_level"); List<String> soureList = sourceDictData.stream().map(SysDictData::getDictValue).collect(Collectors.toList()); hospitalInfos = hospitalInfoMapper.selectNormalHospitalByDictValues("hospital_level", soureList); orderPageDTO.setHospitalIds(hospitalInfos.stream().map(HospitalInfo::getId).collect(Collectors.toList())); } else { sourceDictData = sysDictDataMapper.selectDictDataByType(dto.getZoneType()); List<Area> areaList = tAreaMapper.selectTAreaByAreaType(dto.getZoneType()); //获取所有的市区 areaByParentIdList = areaList.stream().filter(area -> !area.getParentId().equals("0")).collect(Collectors.toList()); List<String> collect = areaByParentIdList.stream().map(Area::getId).collect(Collectors.toList()); hospitalInfos = hospitalInfoMapper.selectHospitalByAreaUrbanIds(collect); orderPageDTO.setHospitalIds(hospitalInfos.stream().map(HospitalInfo::getId).collect(Collectors.toList())); } if (!ObjectUtils.isEmpty(dto.getSources())) { orderPageDTO.setSources(dto.getSources()); } orderPageDTO.setBeginTime(dto.getWriteOffTimeStart()); orderPageDTO.setEndTime(dto.getWriteOffTimeEnd()); examinationOrderList = examinationOrderMapper.selectTExaminationOrderInfoByArea(orderPageDTO); orderPageDTO.setBeginTime(dto.getComparisonStart()); orderPageDTO.setEndTime(dto.getComparisonEnd()); examinationOrderListComparison = examinationOrderMapper.selectTExaminationOrderInfoByArea(orderPageDTO); } //拼装数据 if (!examinationOrderList.isEmpty()) { List<AreaStatisticsVO> areaStatisticsVOList = new ArrayList<>(); int hospitalCountStatistics = (int) examinationOrderList.stream() .map(ExaminationOrderStatisticsVO::getHospitalId) // 获取每个订单的医院 .distinct() .count(); // 计算所有订单的医院量、总订单价格、总退款价格 BigDecimal totalOrderPriceStatistics = BigDecimal.ZERO; BigDecimal totalActualRefundPriceStatistics = BigDecimal.ZERO; for (ExaminationOrderStatisticsVO order : examinationOrderList) { totalOrderPriceStatistics = totalOrderPriceStatistics.add(order.getOrderPrice()); totalActualRefundPriceStatistics = totalActualRefundPriceStatistics.add(order.getActualRefundPrice()); } BigDecimal subtract = totalOrderPriceStatistics.subtract(totalActualRefundPriceStatistics); if (SysDictTypeConstant.PLATFORM_TYPE.equals(dto.getZoneType()) || "hospital_level".equals(dto.getZoneType())) { for (SysDictData dictData : sourceDictData) { AreaStatisticsVO areaStatisticsVOS = new AreaStatisticsVO(); areaStatisticsVOS.setDictLabel(dictData.getDictLabel()); areaStatisticsVOS.setDictValue(dictData.getDictValue()); BigDecimal totalOrderPrice = calculateTotalOrderPrice(examinationOrderList, dictData); BigDecimal totalActualRefundPrice = calculateTotalRefundPrice(examinationOrderList, dictData); // 计算医院量 int hospitalCount = calculateHospitalCount(examinationOrderList, dictData); areaStatisticsVOS.setHospitalInfoQuantity(hospitalCount); //金额 BigDecimal bigDecimal = totalOrderPrice.subtract(totalActualRefundPrice); areaStatisticsVOS.setOrderPriceSum(bigDecimal); BigDecimal totalOrderPriceComparison = calculateTotalOrderPrice(examinationOrderListComparison, dictData); BigDecimal totalActualRefundPriceComparison = calculateTotalRefundPrice(examinationOrderListComparison, dictData); int hospitalCountComparison = calculateHospitalCount(examinationOrderListComparison, dictData); //对比量 areaStatisticsVOS.setHospitalInfoChange(getHospitalInfoChange(hospitalCount - hospitalCountComparison)); //对比金额 BigDecimal bigDecimalComparison = totalOrderPriceComparison.subtract(totalActualRefundPriceComparison); areaStatisticsVOS.setOrderPriceSumChange(getOrderPriceSumChange(bigDecimal, bigDecimalComparison, bigDecimal.subtract(bigDecimalComparison))); //权重 权重=核销金额/总计核销金额*100,计算保留两位小; BigDecimal weight = bigDecimal.divide(subtract, 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2); BigDecimal weightComparison = bigDecimalComparison.divide(subtract, 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2); areaStatisticsVOS.setWeight(weight); areaStatisticsVOS.setWeightChange(getOrderPriceSumChange(weight, weightComparison, weight.subtract(weightComparison))); areaStatisticsVOList.add(areaStatisticsVOS); } } else { String regex = dto.getZoneType()+":(\\d+(?:\\|\\d+)*)"; // 创建 Pattern 对象 Pattern pattern = Pattern.compile(regex); // 创建 matcher 对象 for (SysDictData dictData : sourceDictData) { //区域 List<String> areaCollect = areaByParentIdList.stream() .filter(area -> { Matcher matcher = pattern.matcher(area.getAreaType()); if (matcher.find()) { // 确保匹配成功 String[] split = matcher.group(1).split("\\|"); // 将 split 组转换为 List 并使用 contains List<String> areaTypesList = Arrays.asList(split); return areaTypesList.contains(dictData.getDictValue()); } return false; }) .map(Area::getId) .collect(Collectors.toList()); //医院 List<String> filteredHospitalInfos = hospitalInfos.stream() .filter(hospital -> areaCollect.contains(hospital.getAreaUrban())) .map(HospitalInfo::getId) .collect(Collectors.toList()); List<ExaminationOrderStatisticsVO> ordercollect = examinationOrderList.stream().filter(order -> filteredHospitalInfos.contains(order.getHospitalId())) .collect(Collectors.toList()); List<ExaminationOrderStatisticsVO> ordercollectComparison = examinationOrderListComparison.stream().filter(order -> filteredHospitalInfos.contains(order.getHospitalId())) .collect(Collectors.toList()); AreaStatisticsVO areaStatisticsVOS = new AreaStatisticsVO(); areaStatisticsVOS.setDictLabel(dictData.getDictLabel()); areaStatisticsVOS.setDictValue(dictData.getDictValue()); BigDecimal totalOrderPrice = calculateTotalOrderPrice(ordercollect, dictData); BigDecimal totalActualRefundPrice = calculateTotalRefundPrice(ordercollect, dictData); // 计算医院量 int hospitalCount = calculateHospitalCount(ordercollect, dictData); areaStatisticsVOS.setHospitalInfoQuantity(hospitalCount); //金额 BigDecimal bigDecimal = totalOrderPrice.subtract(totalActualRefundPrice); areaStatisticsVOS.setOrderPriceSum(bigDecimal); BigDecimal totalOrderPriceComparison = calculateTotalOrderPrice(ordercollectComparison, dictData); BigDecimal totalActualRefundPriceComparison = calculateTotalRefundPrice(ordercollectComparison, dictData); int hospitalCountComparison = calculateHospitalCount(ordercollectComparison, dictData); //对比量 areaStatisticsVOS.setHospitalInfoChange(getHospitalInfoChange(hospitalCount - hospitalCountComparison)); //对比金额 BigDecimal bigDecimalComparison = totalOrderPriceComparison.subtract(totalActualRefundPriceComparison); areaStatisticsVOS.setOrderPriceSumChange(getOrderPriceSumChange(bigDecimal, bigDecimalComparison, bigDecimal.subtract(bigDecimalComparison))); //权重 权重=核销金额/总计核销金额*100,计算保留两位小; BigDecimal weight = bigDecimal.divide(subtract, 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2); BigDecimal weightComparison = bigDecimalComparison.divide(subtract, 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2); areaStatisticsVOS.setWeight(weight); areaStatisticsVOS.setWeightChange(getOrderPriceSumChange(weight, weightComparison, weight.subtract(weightComparison))); areaStatisticsVOList.add(areaStatisticsVOS); } } AreaStatisticsVO areaStatisticsVOS = new AreaStatisticsVO(); areaStatisticsVOS.setDictLabel("合计"); areaStatisticsVOS.setHospitalInfoQuantity(hospitalCountStatistics); areaStatisticsVOS.setOrderPriceSum(subtract); areaStatisticsVOList.add(areaStatisticsVOS); map.put("liebiao", areaStatisticsVOList); } return AjaxResult.success(map);优化
07-04
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值