需求引入

你有一个销售单表A 和一个销售单详情表B 和一个收付款记录表C

A---->B 一对多   A---->C一对多

如果一个销售单有两个详情,三条收款记录

对一个销售单 我们想查询出一个结果集 有销售单的id、详情总额、销售单的收款总额

如果你select A  join B on(B和A的外键) 查询出2条记录结果集

如果你select A  join C on(C和A的外键) 查询出3条记录结果集

那你 如果你select A  join B on(B和A的外键)  join C on(C和A的外键) 查询出2*3=6条记录结果集 然后在sum

如果select语句中有聚合函数(sum count )很可能导致查询的结果不符合需求的要求。因为详情总额只需要对两条记录进行sum  收款进行需要三条 而sum之前我们查出来了六条

解决办法

1. 用两条sql查询 然后通过java对结果集进行合并。

缺点:只能对一些简单的需求,如果多个销售单,还要做分页 而且有 付款记录和详情的搜索条件 JAVA很难做

2. 用两条sql查询  然后就是用sql的垂直合并了

select * from (sql1)  join (sql2) on(sql1.销售单的主键=sql2.销售单的主键) 就是把两条sql当成两个子查询

优点:解决了用java操作List进行合并,做不了分页搜索的问题。因为我们用的一个SQL 无论需求怎么搜索分页,都可以搞定

工作中做某张报表的时候发现的。sql语句含有多个一对多关系的时候 注意影响聚合函数的结果。所以采用了先拆分sql,然后根据需求垂直合并。

设计表结构的时,如何避免出现过长的SQL查询

冗余一些字段,比如你需要对收付款记录的某一个字段(比如金额)做sum 把这个字段冗余到一张额外的表里面。

方法一:每次进行收付款的时候加减这个字段。这样做报表的时候就不必再关联收付款记录表做关联求sum了(这样的话 有哪个接口忘记更新收付款就完蛋了 很难排查)

方法二 :每次进行收付款的时候 从新进行一遍收付款的sum放进销售单里面,比较消耗性能。引入消息队列 异步的操作这种接口。

方法三  :收付款的时候多开一个线程,去更新sum字段

当我们把计算逻辑(比如钱的增量)写在SQL里面的时候 可以不用乐观锁,因为SQL会读到其他已经提交的事物,但是如果这个钱是先计算好,然后直接update的 需要用乐观锁

最新文章

  1. Android消息处理机制(Handler、Looper、MessageQueue与Message)
  2. 让ecshop模板支持php运算
  3. [WPF系列]从基础起步学习系列计划
  4. PHP遍历、删除文件夹中的所有文件
  5. uva140 - Bandwidth
  6. wget 命令用法详解
  7. thinkphp中的session()方法
  8. HDOJ 1028 Ignatius and the Princess III(递推)
  9. canvas元素大小与绘图表面大小
  10. MongoDB查询分析
  11. JS Cookie丢失问题
  12. 如何写好CSS系列之表单(form)
  13. LOJ#2723 多边形
  14. JN_0002:Win10禁止U盘拷贝文件的方法
  15. Linux记录-JMX监控JAVA进程
  16. 《2013传智播客视频》-wmv,avi,mp4.目录
  17. mysql错误集合
  18. Spring中JdbcTemplate使用RowMapper
  19. .NET界面控件DevExpress全新发布v18.2.6|附下载
  20. solr 加载 停用/扩展词典

热门文章

  1. SQL 2008发布与订阅
  2. Oracle通过SCN做增量备份修复DG
  3. g++ 学习笔记
  4. 201771010134杨其菊《面向对象程序设计(java)》第十六周学习总结
  5. JavaScript初见
  6. django添加控件
  7. ASP.NET Core使用EntityFrameworkCore CodeFrist
  8. 两条比较实用的mysql导入导出命令
  9. C#实现简单的RPC
  10. $("").append无反应