最近做了一个数据模块的统计,统计企业收款、发票相关的数据,开始统计是比较简单,后面再拆分账套统计就有点小复杂,本文做一个简单的记录。

需求

企业表

企业表t_company有如下字段:标识id、企业名称name:

id name
1 腾讯
2 百度

收款表

企业对应有收款表t_collection有如下字段:标识id、账套account、企业idcompany_id、收款金额amount:

id account company_id amount
1 1 1 30
2 2 1 20
3 1 2 30
4 2 2 40

开票表

开票表t_invoice有如下字段:标识id、账套account、企业idcompany_id、发票金额amount:

id account company_id amount
1 1 1 10
2 2 1 20
3 1 2 30
4 2 2 50

汇总企业统计

现在要做一个统计,统计企业收款金额,以及发票金额,需要将收款表和发票表将company_id做group up操作。开票表也是做类似的操作,企业表和上面的结果做left join连接操作,sql如下:

select tc.id,tc.name,tc2.amount as collection_amount,ti.amount as invoice_amunt from t_company tc
left join (
select company_id,sum(amount) as amount from t_collection group by company_id
) tc2 on tc.id = tc2.company_id
left join (
select company_id,sum(amount) as amount from t_invoice group by company_id
) ti on tc.id = ti.company_id

查询结果:

id name collection_amount invoice_amunt
1 腾讯 50 30
2 百度 70 80

再分账套做汇总(重点)

在上面统计的基础上,再拆分账套统计。

收款表和发票表做账套的拆分,和企业表做关联:

select tc.id,tc.name,tc2.amount as collection_amount,ti.amount as invoice_amunt from t_company tc
left join (
select company_id,account,sum(amount) as amount from t_collection
group by company_id,account
) tc2 on tc.id = tc2.company_id
left join (
select company_id,account,sum(amount) as amount from t_invoice
group by company_id,account
) ti on tc.id = ti.company_id and tc2.account = ti.account

首先是将收款表做账套的拆分,然后关联发票表的账套拆分。看似没有问题,但是left join返回左边的所有记录,以及右边字段相等的数据。

这样就有一个问题:

如果左边表没有的数据,右边的表也不会查出来。比如以上查询收款表不存在的账套,发票表存在账套也不会查出来。这就是left join的局限性。

全表连接解决方案一:

MySQL有left join、right join应该也有full join全表连接。

但是MySQL是不支持full join全表连接。

网上也有解决方案使用union替换full_join,思路是左表左连接右边,左表右连接右边,将上面的两个结果union连接起来:

select * from t1 left join t2 on t1.id = t2.id
union
select * from t1 right join t2 on t1.id = t2.id;

上面只是两个表的关联,如果三个表或者更多的关联,写起来就比较繁琐了。

全表连接解决方案二:

全表连接就是一个没有限制的左表连接,就是去掉on关联条件,

要left join所有的账套,首先要显示全所有的账套,企业表关联账套表,但是两个表是没有关联的,需要去掉on后面的关联条件,但是MySQL语法连接后面必须要加on,将约束条件改成1 = 1即可:

 select tc.id,tc.name,ta.id as account from t_company tc left join t_account ta on 1 = 1
id name account
1 腾讯 1
1 腾讯 2
2 百度 1
2 百度 2

查询出所有的公司账套之后,再left join收款表和发票表:


select tc.id,tc.name,tc.account,tc2.amount as collection_amount,ti.amount as invoice_amunt from (
select tc.id,tc.name,ta.id as account from t_company tc left join t_account ta on 1 = 1
)tc
left join (
select company_id,account,sum(amount) as amount from t_collection group by company_id,account
) tc2 on tc.id = tc2.company_id and tc.account = tc2.account
left join (
select company_id,account,sum(amount) as amount from t_invoice group by company_id,account
) ti on tc.id = ti.company_id and tc.account = ti.account

结果:

id name account collection_amount invoice_amunt
1 腾讯 1 30 10
1 腾讯 2 20 20
2 百度 1 30 30
2 百度 2 40 50

总结

  • 企业分组统计收款和发票表,只需要对企业做group by分组即可。
  • 企业和账套一起分组,left join只会统计左边存在的数据,而需要统计两边都存在的数据。
    • 使用union多表查询比较繁琐。
    • left join使用on 1 = 1查询不添加限制条件,查询所有公司的账套,再关联发票和收款。

参考

使用LEFT JOIN 统计左右存在的数据的更多相关文章

  1. 从数据表中随机抽取n条数据有哪几种方法(join实现可以先查数据然后再拼接)

    从数据表中随机抽取n条数据有哪几种方法(join实现可以先查数据然后再拼接) 一.总结 一句话总结:最好的是这个:"SELECT * FROM table WHERE id >= (( ...

  2. 分享一个Python脚本--统计redis key类型数据大小分布

    概述 今天主要介绍怎么统计redis key类型数据大小分布. 原理:使用redis命令: scan.pipline.type 和 debug object 来得到 redis key 信息. 脚本 ...

  3. Mysql统计每年每个月的数据——详细教程

    Mysql统计每年每个月的数据(前端页面统计图实现) 最终想实现的效果图,在这里就不多废话了,直接上效果图,由于测试数据有几个月是为0的,所以数据图看着会有点怪怪. 接下来是数据库的两个表,这里直接给 ...

  4. 记录sql中统计近五天数据的口径(While+IF)

    话不多说,直接上码↓ IF OBJECT_ID('tempdb..#Table') IS NOT NULL BEGIN DROP TABLE #Table; END; DECLARE @tbRange ...

  5. shell 统计GMT0 时区的数据

    和某个供应商核对数据,对方是GMT+0时区,我方报表默认北京时间,无法修改为GMT0, 对excel中按照小时级别的数据导出到excel处理,然后转为文本文件,shell转为GMT0进行统计: 前期处 ...

  6. mysql join 的同时可以筛选数据

    看sql ) ) group by a.id; 这里面用了多个子查询,与join关联. 其中 不仅有关联条件,还对sh_mall_goods表进行了筛选,只选出mall_id为9的数据,进行关联. 这 ...

  7. VBA怎样统计同一类型的数据的总和

    今天是2014-11-01 是周末,忙了一周了,最终能够闲下来了.想起近期工作用到的VBA的一个场景,结合VBA的数组,所以就想试试看.结果还好.出来了.这年头,又玩起了VB了,经过多时才接受了VB的 ...

  8. 下单快发货慢:一个 JOIN SQL 引起 SqlClient 读取数据慢的奇特问题

    最近遇到一个非常奇特的问题,在一个 ASP.NET Core 项目中从 SQL Server 2008 R2 中查询获取 100 条记录竟然耗时 10 多秒,如果是查询本身慢,那到不是什么奇特的问题. ...

  9. 使用MTA HTML5统计API来分析数据

    使用MTA HTML5统计API来分析数据 在开发个人博客的时候,用到了腾讯移动分析(MTA),相比其他数据统计平台来说我喜欢她的简洁高效,易上手,同时文档也比较全面,提供了数据接口供用户调用. 在看 ...

随机推荐

  1. Map集合的遍历方式以及TreeMap集合保存自定义对象实现比较的Comparable和Comparator两种方式

    Map集合的特点 1.Map集合中保存的都是键值对,键和值是一一对应的 2.一个映射不能包含重复的值 3.每个键最多只能映射到一个值上 Map接口和Collection接口的不同 Map是双列集合的根 ...

  2. 开源深度思考 - In Community We Trust

    作者 | 黄东旭,PingCAP 联合创始人&CTO 出品 | CSDN(ID:CSDNnews) 业界一直流传着黄东旭的传说:小学三年级开始写代码,四五年级学习C语言,初中毕业时,已经能够用 ...

  3. java学习第一天.day02

    整数类型常量 整数类型的常量JVM默认使用 int 类型来存储 小数类型类型 小数类型的常量JVM默认使用 double 类型来存储 . ASCII表 A在码表的顺序是65,a在码表的顺序是97

  4. @babel/runtime 和 @babel/plugin-transform-runtime 两个的作用是什么

    Babel 最基础的功能就是将采用 ECMAScript 2015+ 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中. 最基础的依赖包也就是 ...

  5. 在微信小程序中,如何获取 for 循环的 index

    微信小程序中,for 循环的 index(索引值)可以用wx:for-index="index"来获取. <view class="item" wx:fo ...

  6. Java SE 14 新增特性

    Java SE 14 新增特性 作者:Grey 原文地址:Java SE 14 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...

  7. idea主类main左侧栏启动按钮消失原因

    今天在开发完一个小项目后,打开idea发现我的springboot项目的启动类左侧栏的按钮消失了,然后我又去看了看mapp等文件的调转也全部消失了,我就很纳闷是不是idea配置坏了,赶忙点击导航栏的按 ...

  8. 洛谷P4135 作诗(不一样的分块)

    题面 给定一个长度为 n n n 的整数序列 A A A ,序列中每个数在 [ 1 , c ] [1,c] [1,c] 范围内.有 m m m 次询问,每次询问查询一个区间 [ l , r ] [l, ...

  9. CF914G Sum the Fibonacci (快速沃尔什变换FWT + 子集卷积)

    题面 题解 这是一道FWT和子集卷积的应用题. 我们先设 cnt[x] 表示 Si = x 的 i 的数量,那么 这里的Nab[x]指满足条件的 Sa|Sb=x.Sa&Sb=0 的(a,b)二 ...

  10. 声明式HTTP客户端-Feign 使用入门详解

    什么是 OpenFeign OpenFeign (以下统一简称为 Feign) 是 Netflix 开源的声明式 HTTP 客户端,集成了 Ribbon 的负载均衡.轮询算法和 RestTemplat ...