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

本文介绍了一个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

解释一下列语句的语法,纯文本输出.// sky-server\src\main\java\com\sky\service\impl\ReportServiceImpl.java package com.sky.service.impl; import com.sky.dto.GoodsSalesDTO; import com.sky.entity.Orders; import com.sky.mapper.OrderMapper; import com.sky.mapper.UserMapper; import com.sky.service.ReportService; import com.sky.service.WorkspaceService; import com.sky.vo.*; import org.apache.commons.lang3.StringUtils; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.InputStream; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @Service public class ReportServiceImpl implements ReportService { @Autowired private OrderMapper orderMapper; @Autowired private UserMapper userMapper; @Autowired private WorkspaceService workspaceService; /** * 统计指定时间区间内的营业额数据 * @param begin * @param end * @return */ public TurnoverReportVO getTurnoverStatistics(LocalDate begin, LocalDate end) { //当前集合用于存放从begin到end范围内的每天的日期 List<LocalDate> dateList = new ArrayList<>(); dateList.add(begin); while (!begin.equals(end)){ begin = begin.plusDays(1); dateList.add(begin); } //存放每天的营业额 List<Double> turnoverList = new ArrayList<>(); for (LocalDate date : dateList) { //查询date日期对应的营业额数据,营业额是指:状态为”已完成“的订单金额合计 LocalDateTime begintime = LocalDateTime.of(date, LocalTime.MIN); LocalDateTime endtime = LocalDateTime.of(date, LocalTime.MAX); //select sum(amout) from ordes where order_time > beginTime and order_time < endTime and status = 5 Map map = new HashMap<>(); map.put("begin",begintime); map.put("end",endtime); map.put("status", Orders.COMPLETED); Double turnover = orderMapper.sumByMap(map); turnover = turnover == null ? 0.0:turnover; turnoverList.add(turnover); } //封装返回结果 TurnoverReportVO turnoverReportVO = new TurnoverReportVO(); turnoverReportVO.setDateList(StringUtils.join(dateList,",")); turnoverReportVO.setTurnoverList(StringUtils.join(turnoverList,",")); return turnoverReportVO; } /** * 统计指定时间区间内的用户数据 * @param begin * @param end * @return */ public UserReportVO getUserStatistics(LocalDate begin, LocalDate end) { //当前集合用于存放从begin到end范围内的每天的日期 List<LocalDate> dateList = new ArrayList<>(); dateList.add(begin); while (!begin.equals(end)){ begin = begin.plusDays(1); dateList.add(begin); } //存放每天的新增用户量 select count(id) from user where create_time < ? and create_time > ? List<Integer> newUserList = new ArrayList<>(); //存放每天的总用户量 select count(id) from user where create_time < ? List<Integer> totalUserList = new ArrayList<>(); for (LocalDate date : dateList) { LocalDateTime begintime = LocalDateTime.of(date, LocalTime.MIN); LocalDateTime endtime = LocalDateTime.of(date, LocalTime.MAX); Map map = new HashMap(); map.put("end",endtime); //总用户量 Integer totalUser = userMapper.countByMap(map); map.put("begin",begintime); //新增用户量 Integer newUser = userMapper.countByMap(map); newUserList.add(newUser); totalUserList.add(totalUser); } //封装返回结果 UserReportVO userReportVO = new UserReportVO(); userReportVO.setDateList(StringUtils.join(dateList,",")); userReportVO.setTotalUserList(StringUtils.join(totalUserList,",")); userReportVO.setNewUserList(StringUtils.join(newUserList,",")); return userReportVO; } /** * 统计指定时间区间内的订单数据 * @param begin * @param end * @return */ public OrderReportVO getOrdersStatistics(LocalDate begin, LocalDate end) { //存放从begin到end之间的每天对应的日期 List<LocalDate> dateList = new ArrayList<>(); dateList.add(begin); while (!begin.equals(end)){ begin = begin.plusDays(1); dateList.add(begin); } //存放每天的订单总 List<Integer> orderConutList = new ArrayList<>(); //存放每天的有效订单 List<Integer> validOrderConutList = new ArrayList<>(); //遍历dateList集合,查询每天的有效订单和订单总 for (LocalDate date : dateList) { //查询每天的订单总 select count(id) from orders where order_time > ? and order_time < ? LocalDateTime beginTime = LocalDateTime.of(date,LocalTime.MIN); LocalDateTime endTime = LocalDateTime.of(date,LocalTime.MAX); Integer orderCount = getOrderCount(beginTime,endTime,null); //查询每天的有效订单 select count(id) from orders where order_time > ? and order_time < ? and status = 5 Integer validOrdersCount = getOrderCount(beginTime,endTime,Orders.COMPLETED); orderConutList.add(orderCount); validOrderConutList.add(validOrdersCount); } //计算时间区间内的订单总量 Integer totalOrderCount = orderConutList.stream().reduce(Integer::sum).get(); //计算时间区间内的有效订单量 Integer validOrderCount = validOrderConutList.stream().reduce(Integer::sum).get(); Double orderCompletionRate = 0.0; if(totalOrderCount != 0){ orderCompletionRate = validOrderCount.doubleValue() / totalOrderCount; } OrderReportVO orderReportVO = new OrderReportVO(); orderReportVO.setDateList(StringUtils.join(dateList,",")); orderReportVO.setOrderCountList(StringUtils.join(orderConutList,",")); orderReportVO.setValidOrderCountList(StringUtils.join(validOrderConutList,",")); orderReportVO.setTotalOrderCount(totalOrderCount); orderReportVO.setValidOrderCount(validOrderCount); orderReportVO.setOrderCompletionRate(orderCompletionRate); return orderReportVO; } /** * 根据条件统计订单量 * @param beginTime * @param endTime * @param status * @return */ private Integer getOrderCount(LocalDateTime beginTime, LocalDateTime endTime, Integer status) { Map map = new HashMap<>(); map.put("begin",beginTime); map.put("end",endTime); map.put("status",status); return orderMapper.getOrderCount(map); } /** * 统计指定时间区间内的销量排名前10 * @param begin * @param end * @return */ public SalesTop10ReportVO getSalesTop10(LocalDate begin, LocalDate end) { LocalDateTime beginTime = LocalDateTime.of(begin,LocalTime.MIN); LocalDateTime endTime = LocalDateTime.of(end,LocalTime.MAX); List<GoodsSalesDTO> salesTop10 = orderMapper.getSalesTop10(beginTime,endTime); List<String> names = salesTop10.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList()); String nameList = StringUtils.join(names,","); List<Integer> numbers = salesTop10.stream().map(GoodsSalesDTO::getNumber).collect(Collectors.toList()); String numberList = StringUtils.join(numbers,","); return new SalesTop10ReportVO(nameList,numberList); } /** * 导出运营数据 * @param response */ public void exportBusinessData(HttpServletResponse response) { //1.查询数据库,获取营业数据-----查询最近30天的运营数据 LocalDate dateBegin = LocalDate.now().minusDays(30); LocalDate dateEnd = LocalDate.now().minusDays(1); //查询概览数据 BusinessDataVO businessDataVO = workspaceService.getBusinessData(LocalDateTime.of(dateBegin,LocalTime.MIN),LocalDateTime.of(dateEnd,LocalTime.MAX)); //2.通过POI将数据写入到EXCEL文件中 InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/运营数据模板.xlsx"); try { //基于模板文件创建一个新的Excel文件 XSSFWorkbook excel = new XSSFWorkbook(in); //获取格文件的Sheet页 XSSFSheet sheet = excel.getSheet("Sheet1"); //填充数据 sheet.getRow(1).getCell(1).setCellValue("时间:"+dateBegin+"至"+dateEnd); //获得第4行 XSSFRow row = sheet.getRow(3); row.getCell(2).setCellValue(businessDataVO.getTurnover()); row.getCell(4).setCellValue(businessDataVO.getOrderCompletionRate()); row.getCell(6).setCellValue(businessDataVO.getNewUsers()); //获得第5行 row = sheet.getRow(4); row.getCell(2).setCellValue(businessDataVO.getValidOrderCount()); row.getCell(4).setCellValue(businessDataVO.getUnitPrice()); //填充明细 for (int i = 0; i < 30; i++) { LocalDate date = dateBegin.plusDays(i); //查询某一天的营业额数据 BusinessDataVO businessData = workspaceService.getBusinessData(LocalDateTime.of(date,LocalTime.MIN),LocalDateTime.of(date,LocalTime.MAX)); //获得某一行 row = sheet.getRow(7+i); row.getCell(1).setCellValue(date.toString()); row.getCell(2).setCellValue(businessData.getTurnover()); row.getCell(3).setCellValue(businessData.getValidOrderCount()); row.getCell(4).setCellValue(businessData.getOrderCompletionRate()); row.getCell(5).setCellValue(businessData.getUnitPrice()); row.getCell(6).setCellValue(businessData.getNewUsers()); } //3.通过输出流将Excel文件下载到客户端浏览器 ServletOutputStream out = response.getOutputStream(); excel.write(out); //关闭资源 out.close(); excel.close(); }catch (Exception e){ e.printStackTrace(); } } }
最新发布
10-25
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
### 去重后的订单量和总金额的 SQL 查询 为了计算去重后的订单量和总金额,可以结合 `DISTINCT` 和 `SUM` 函来实现。以下是具体的解决方案: #### 1. 使用 `COUNT(DISTINCT ...)` 统计唯一订单 可以通过 `COUNT(DISTINCT column_name)` 来统计唯一的订单量。此方法会自动去除重复的订单记录并返回唯一的订单。 #### 2. 使用 `SUM(...)` 统计总金额 对于总金额的计算,可以直接使用 `SUM(column_name * another_column_name)` 的方式,其中涉及乘法运算的部分可以根据实际需求调整。 综合以上两点,假设有一个名为 `OrderItems` 的,包含以下字段: - `order_id`: 订单ID - `item_price`: 商品单价 - `quantity`: 商品量 那么完整的 SQL 查询语句如下所示: ```sql SELECT COUNT(DISTINCT order_id) AS unique_orders, SUM(item_price * quantity) AS total_amount FROM OrderItems; ``` 上述查询中: - `COUNT(DISTINCT order_id)` 负责统计唯一订单的量[^2]。 - `SUM(item_price * quantity)` 则用于计算所有商品总价[^1]。 如果数据源是一个更复杂的场景,例如需要按日期或其他条件分组,则可以在查询中引入额外的过滤器或聚合逻辑。例如基于引用中的另一个例子[^4],我们可以扩展到每日订单量统计的情况: ```sql SELECT Date, COUNT(DISTINCT Order_id) AS daily_unique_orders, SUM(amount) AS daily_total_amount FROM STG.ORDER GROUP BY Date; ``` 这段代码实现了按照日期维度分别统计每天的唯一订单和当天的总交易额。 --- #### 注意事项 当处理大数据集时,应确保索引优化得当以提高性能;另外还需注意可能存在的 NULL 影响最终结果准确性。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值