这几天弄一个牵涉到收房租的项目,需要统计房租收入、支出和退款情况,即每年每个月的这三种情况。
要求:
1、三种情况弄在一个页面中,第一列月份、第二列收入情况、第三列支出情况、第四列退款;
2、并不是显示12个月的数据,而是哪个月份有数据就显示哪个月的;
3、最后一行为合计列,显示三种情况的各个合计。
三种情况对应的表如下:
收入:table2 收款金额:field14 收款日期:field16
支出:table4 支出金额:field4 支出日期:field3
退款:table3 退款金额:field14 退款日期:field15
具体情况如图:
这里的处理方式是:用SQL写出个视图,然后直接从视图中取数据。SQL如下:
CREATE VIEW [dbo].[incomeOrOutView] AS SELECT CAST(aa.f1 AS varchar(10)) AS field1, CAST(aa.f2 AS varchar(10)) AS field2, ISNULL(bb.f1, 0) AS field3, ISNULL(cc.f1, 0) AS field4, ISNULL(dd.f1, 0) AS field5 FROM (SELECT DISTINCT YEAR(f1) AS f1, MONTH(f1) AS f2 FROM (SELECT field16 AS f1 FROM dbo.table2 UNION ALL SELECT field3 AS f1 FROM dbo.table4 WHERE (field5 = '完成') UNION ALL SELECT field15 AS f1 FROM dbo.table3) AS ee) AS aa LEFT OUTER JOIN (SELECT SUM(field14) AS f1, YEAR(field16) AS f2, MONTH(field16) AS f3 FROM dbo.table2 AS table4_1 GROUP BY YEAR(field16), MONTH(field16)) AS bb ON aa.f1 = bb.f2 AND aa.f2 = bb.f3 LEFT OUTER JOIN (SELECT SUM(field4) AS f1, YEAR(field3) AS f2, MONTH(field3) AS f3 FROM dbo.table4 AS table5_1 WHERE (field5 = '完成') GROUP BY YEAR(field3), MONTH(field3)) AS cc ON aa.f1 = cc.f2 AND aa.f2 = cc.f3 LEFT OUTER JOIN (SELECT SUM(field14) AS f1, YEAR(field15) AS f2, MONTH(field15) AS f3 FROM dbo.table3 AS table6_1 GROUP BY YEAR(field15), MONTH(field15)) AS dd ON aa.f1 = dd.f2 AND aa.f2 = dd.f3
简单说明一下:
1、从table2、table3、table4三个表中日期,得到所有有记录的日期数据,作为表ee
2、对表ee取年份和月份,并去除冗余,得到所有记录中的有的年份和月份(满足要求中的第二条:哪个月份有数据就显示哪个月的),作为表aa
3、分别从table2、table3、table4三个表取相应数据并与表aa联结,联结条件为:年份和月份相同,得到基本数据结果。
最后添加过滤数据——只显示今年的数据,并添加合计列:
select * from incomeOrOutView where field1 = year(getdate()) UNION ALL SELECT year(getdate()), '合计', ISNULL(sum(field3),0), ISNULL(sum(field4),0), ISNULL(sum(field5),0) FROM incomeOrOutView WHERE field1 = year(getdate())
问题解决到这里,看起来应该是差不多了,若把另一种考量加进来,似乎也合情合理:
每个月交房租就一定是当月的1号-30号吗?,或者1-30号交的钱就一定是当前月的?我要是每个月15号过后就算下个月的呢?
对,后来我就碰到了这个问题,要求:上个月10到这个月9号,算这个月的。即:从2015-7-10到2015-8-9算8月份的。
有一个很简单的方法可以处理掉这个问题,就是在录数据的时候就标记下是收哪个月的,这样在统计的时候就可以直接取值而不需要特殊判断了。弄的系统中的确有这么一字段也是必填项,建议客户用这个,结果客户说:我这个数据是用来告诉我自己这个钱是交的几月份的,但是我做账还得用录入的时间。很无语,只能接着改。
改的思路是:先弄一个SQL,将所有的数据按照选定的日期拼接起来,在添加字段用来标记这条数据应该是哪个月的,这样到时候直接取值,具体SQL如下:
--1、创建视图用来拼接符合条件的数据 CREATE VIEW [dbo].[subInOrOutView] AS SELECT field14 AS f1, field16 AS f2, YEAR(field16) AS f3, (CASE WHEN t2.field16 BETWEEN '' + CAST(year(t2.field16) AS varchar(50)) + '-' + CAST((month(t2.field16)) AS varchar(50)) + '-10 00:00:00' AND '' + CAST(year(t2.field16) AS varchar(50)) + '-' + CAST(month(t2.field16) + 1 AS varchar(50)) + '-9 23:59:59' THEN month(t2.field16) + 1 ELSE month(t2.field16) END) AS f4, 2 AS f5 FROM dbo.table2 AS t2 UNION ALL SELECT field4 AS f1, field3 AS f2, YEAR(field3) AS f3, (CASE WHEN t4.field3 BETWEEN '' + CAST(year(t4.field3) AS varchar(50)) + '-' + CAST((month(t4.field3)) AS varchar(50)) + '-10 00:00:00' AND '' + CAST(year(t4.field3) AS varchar(50)) + '-' + CAST(month(t4.field3) + 1 AS varchar(50)) + '-9 23:59:59' THEN month(t4.field3) + 1 ELSE month(t4.field3) END) AS f4, 4 AS f5 FROM dbo.table4 AS t4 WHERE (field5 = '完成') UNION ALL SELECT field14 AS f1, field15 AS f2, YEAR(field15) AS f3, (CASE WHEN t3.field15 BETWEEN '' + CAST(year(t3.field15) AS varchar(50)) + '-' + CAST((month(t3.field15)) AS varchar(50)) + '-10 00:00:00' AND '' + CAST(year(t3.field15) AS varchar(50)) + '-' + CAST(month(t3.field15) + 1 AS varchar(50)) + '-9 23:59:59' THEN month(t3.field15) + 1 ELSE month(t3.field15) END) AS f4, 3 AS f5 FROM dbo.table3 AS t3 --2、修改原有视图 ALTER VIEW [dbo].[incomeOrOutView] AS SELECT CAST(aa.f1 AS varchar(10)) AS field1, CAST(aa.f2 AS varchar(10)) AS field2, ISNULL(bb.f1, 0) AS field3, ISNULL(cc.f1, 0) AS field4, ISNULL(dd.f1, 0) AS field5 FROM (SELECT DISTINCT f3 AS f1, f4 AS f2 FROM dbo.subInOrOutView) AS aa LEFT OUTER JOIN (SELECT SUM(f1) AS f1, f3 AS f2, f4 AS f3 FROM dbo.subInOrOutView AS subInOrOutView_3 WHERE (f5 = 2) GROUP BY f3, f4) AS bb ON aa.f1 = bb.f2 AND aa.f2 = bb.f3 LEFT OUTER JOIN (SELECT SUM(f1) AS f1, f3 AS f2, f4 AS f3 FROM dbo.subInOrOutView AS subInOrOutView_2 WHERE (f5 = 4) GROUP BY f3, f4) AS cc ON aa.f1 = cc.f2 AND aa.f2 = cc.f3 LEFT OUTER JOIN (SELECT SUM(f1) AS f1, f3 AS f2, f4 AS f3 FROM dbo.subInOrOutView AS subInOrOutView_1 WHERE (f5 = 3) GROUP BY f3, f4) AS dd ON aa.f1 = dd.f2 AND aa.f2 = dd.f3
也简单说明一下:
1、先判断日期是否在指定的时间范围(这个月10号到下个月9号)之内,若是在那么月份就设置为下个月的,即当前月+1;否则就设置为当前月份;
2、添加字段用来区分这个数据是收入、支出还是退款,即f5所代表的2、4、3;
3、修改的视图中直接从筛选好的月份里面取数据并和其他数据联结查询得到最后结果;
若不想弄前面那个视图,还有一个更简单的,就是在每个表上加个触发器用来监听三个日期,每当日期有变化时,就计算一下,看看它是属于哪个月份的,最后做统计的时候直接取那个字段的月份就成。
相关推荐
综上所述,解决“sql计算某个时间为甲乙丙丁中的哪一个班组”的问题,关键在于理解并运用Oracle SQL的日期函数、时间比较、CASE语句以及可能的分组统计。具体实现应根据实际的班组划分规则和数据表结构进行调整。在...
使用这个函数,你可以方便地查询任何日期属于其前一个月的第几个自然周,这对于统计分析或业务处理非常有用。例如,你可以结合其他业务数据,找出特定日期范围内各周的销售趋势、用户活跃度等指标。 在实际应用中,...
这里我们将深入探讨如何使用SQL语句来实现这个目标,以及涉及到的一些关键函数和概念。 首先,我们来看如何生成一系列的随机数,这在模拟数据或者测试场景中非常有用。在提供的示例中,使用了`DBMS_RANDOM.VALUE`...
在SQL Server中,自定义分割月功能是一种特殊的时间粒度处理方法,主要用于处理非标准的月份统计需求。这种功能允许用户根据特定的日期索引值(1-31)来划分月份,使得某个日期可能属于从指定索引值到下个月相同索引...
在做数据库的统计时,经常会需要根据年、月、日来统计数据,然后配合echarts来制作可视化效果。 数据库:MySQL 思路 按照时间维度进行统计的前提是...带有英文前缀的月中的天 %d 月的天,数值(00-31) %e 月的天,数
首先,旬是指一个月中的三个时间段:上旬(1-10日)、中旬(11-20日)和下旬(21-30/31日)。在提供的代码中,有两个自定义函数,`fd_lastxunstart` 和 `fd_lastxunend`,用于分别获取上一旬的开始日期和结束日期。 ...
**问题1:** 是否可以使用批量 SQL 或存储过程来计算一个月中的天数? **解答1:** 一种方法是使用 `datepart` 和 `dateadd` 函数结合来计算指定月份最后一天的日期,再通过获取该日期的天数部分来得出一个月的总...
这些函数在处理时间相关的查询和计算时非常有用,比如筛选过去30天的数据,或者统计特定季度的销售数据。 在面试中,了解并能够熟练运用这些知识点对于评估一个候选人在MySQL领域的技能和经验至关重要。同时,还...
- **功能**:返回指定日期在一个月中是第几天,范围为1至31。 - **示例**: ```sql SELECT DAYOFMONTH('1998-02-03'); ``` 返回值为3,表示1998年2月3日是一月份的第三天。 - **应用场景**: - 用于统计特定...
Oracle数据库是世界上最广泛使用的数据库系统之一,...在实际开发中,熟练掌握这些函数的用法,能大大提高SQL查询的效率和代码的可读性。通过不断实践和探索,开发者可以更有效地利用Oracle数据库进行数据管理和分析。
VFP 常用命令、函数、属性、事件和方法 ...* CALCULATE:对表中的字段或包含字段的表达式进行财务和统计操作。 VFP 的命令、函数、属性、事件和方法提供了强大的功能来帮助开发者快速构建数据库应用程序。
- **聚合函数**:如 SUMX、AVERAGE、COUNT 等,用于对数据集进行各种统计聚合操作。 ### Power BI On-Premise的安装及部署 Power BI On-Premise指的是Power BI的本地版本,即Power BI Report Server,它允许企业将...
这个函数在处理与具体日期相关的任务时非常实用,比如统计每月每天的销售额或记录生日等。 这些日期函数在SQL查询中经常组合使用,以满足各种复杂的日期过滤和分析需求。例如,如果你想找出2013年6月的所有订单,你...
- **Week**: 使用`WW`表示年中的周数(例如:`44`),使用`W`表示月中的周数(例如:`1`)。 ### 日期转换函数 #### to_date 和 to_char 函数 1. **to_date**: 将字符串转换为日期类型。 - 示例:`SELECT TO_...
总结来说,Oracle SQL提供了多种方式来获取当前日期在一年或一个月中的星期数,你可以根据实际需求选择适合的格式元素,如 `ww` 或 `iw`。而在Java中,可以使用`Calendar`类进行类似的日期处理和计算。这些技巧在...
`DAYOFWEEK()`, `DAYOFMONTH()`, 和 `DAYOFYEAR()`分别返回星期、月中的天数和年中的天数;`DAYNAME()`返回星期名;`FROM_UNIXTIME()`将Unix时间戳转换为日期;`NOW()`返回当前日期和时间;`STR_TO_DATE()`将字符串...
一个crontab文件中包含有六个字段:分钟(0-59)、小时(0-23)、月中的第几天(1-31)、月份(1-12)、星期几(0-6,其中0=星期日)。 - 要编辑一个crontab文件,输入:`crontab -e` - 要查看一个crontab文件,...
- **DAYOFMONTH(date)**: 返回`date`是一个月中的第几天(1~31)。 - **DAYOFYEAR(date)**: 返回`date`是一年中的第几天(1~366)。 - **DAYNAME(date)**: 返回`date`的星期名称。 - **FROM_UNIXTIME(ts,fmt)**: 将...
- **用途**: `netstat` 命令用来显示与 IP、TCP、UDP 和 ICMP 协议相关的统计数据。 - **常用选项**: `-a` 显示所有连接; `-n` 数字形式显示地址和端口; `-t` 显示 TCP 连接; `-u` 显示 UDP 连接。 - **应用场景**: ...