zoukankan      html  css  js  c++  java
  • 多条SQL语句对查询结果集的垂直合并,以及表设计时如何冗余字段

    需求引入

    你有一个销售单表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的 需要用乐观锁

  • 相关阅读:
    zabbix 监控机器监听的端口 + 触发器 表达式理解
    php关于文件上传的两个配置项说明
    linux cron计划任务防止多个任务同时运行
    php注册自动加载函数
    linux 下查看机器是cpu是几核的
    laravel容器类make方法解释
    laravel php门面模式
    js获取当前页面的url地址
    php编码规范
    laravel console handle 传参方法
  • 原文地址:https://www.cnblogs.com/ssskkk/p/8548487.html
Copyright © 2011-2022 走看看