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

需求

企业表

企业表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_idgroup 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的局限性。

全表连接解决方案一:

MySQLleft joinright 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. Ceph 块存储 创建的image 映射成块设备

    将创建的volume1映射成块设备 [root@mysql-server ceph]# rbd map rbd_pool/volume1 rbd: sysfs write failed RBD ima ...

  2. Host long.com not found: 2(SERVFAIL)

    环境: centos  7.9 地址:192.168.200.100 相关配置 name.conf文件: named.zones文件: 正反解析文件: 重启DNS服务: 1 [root@server ...

  3. Java开发学习(二十六)----SpringMVC返回响应结果

    SpringMVC接收到请求和数据后,进行了一些处理,当然这个处理可以是转发给Service,Service层再调用Dao层完成的,不管怎样,处理完以后,都需要将结果告知给用户. 比如:根据用户ID查 ...

  4. SpringBoot读取.yml配置文件最常见的两种方式-源码及其在nacos的应用

    一.前言 我们在开发中会经常遇到一些可能会变的值,比如数据库的密码,一些关键链接的配置等等. 都需要我们写在配置文件中,这样可以把这些配置文件放到nacos上进行管理,修改nacos的配置,咱们发布的 ...

  5. 文心大模型api使用

    文心大模型api使用 首先,我们要获取硅谷社区的连个key 复制两个api备用 获取Access Token 获取access_token示例代码 之后就会输出 作文创作 作文创作:作文创作接口基于文 ...

  6. HCNP Routing&Switching之MAC地址防漂移

    前文我们了解了二层端口安全技术相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/16631222.html:今天我们来聊一聊MAC地址防漂移技术: 首先我 ...

  7. Filter(过滤器)、ThreadLocal(本地线程)、Listener(监听器)

    Filter(过滤器) Filter过滤器它的作用是:拦截请求,过滤响应. 过滤器链 1)执行的顺序依次是: A B C Demo03 C2 B2 A2 2)如果采取的是注解的方式进行配置,那么过滤器 ...

  8. 不想当Window的Dialog不是一个好Modal,弹窗翻身记

    弹窗是我们熟视无睹的一种交互方式,经常用到,但从没好好想过这种交互行为背后的意义... 弹窗是Windows的灵魂 Windows的灵魂是什么?当然是Window,当方便快捷的多窗口进入人们视野的时候 ...

  9. [CG] 顶点动画贴图 (Vertex Animation Texture, VAT)

    什么是顶点动画? 简单来说,通过改变网格顶点的位置,使网格变形从而做成的动画.顶点动画的灵活度要远远高于骨骼动画.骨骼动画是靠骨骼(一堆有层级结构的节点,数量应该是远远小于网格顶点的数量的)的变化来驱 ...

  10. 使用 MAUI 在 Windows 和 Linux 上绘制 PPT 的图表

    我在做一个图表工具软件,这个软件使用 MAUI 开发.我的需求是图表的内容需要和 PPT 的图表对接,需要用到 OpenXML 解析 PPT 内容,读取到 PPT 图表元素的内容,接着使用 MAUI ...