SQL server报表同比与环比查询
SQL 查询同比,环比
d.Sales as 上月销售总量,
case when d.Sales is null or d.Sales=0 then '无穷大' else cast(cast((isnull(c.Sales, 0)-isnull(d.Sales,0))*100/isnull(d.Sales, 0) as decimal(10,2)) as varchar(50))+'%' end as 环比
select 1, '营销一部', 300, '2006-7-1'
UNION ALL select 2, '营销二部', 500, '2006-7-1'
UNION ALL select 3, '营销三部', 800, '2006-8-1'
UNION ALL select 4, '营销一部', 600, '2006-8-1'
on c.SalesDate=d.SalesDate and c.DepartName=d.DepartName
//得到同比
select c.DepartName as 部门, convert(varchar(10), c.SalesDate, 23) as 对比年月, c.Sales as 本月销售总量, d.Sales as 去年同期销售总量, case when d.Sales is null or d.Sales=0 then '无穷大' else cast(cast((isnull(c.Sales, 0)-isnull(d.Sales,0))*100/isnull(d.Sales, 0) as decimal(10,2)) as varchar(50))+'%' end as 同比 from SalesDetail c left join
sqlserver查询函数用法
sqlserver查询函数用法SQL Server是一种常见的关系型数据库管理系统(RDBMS),它使用结构化查询语言(SQL)来管理和操作数据。
SQL Server提供了许多功能强大的查询函数,可以帮助数据库开发人员更轻松地从数据库中检索和处理数据。
在本文中,我们将一步一步地介绍SQL Server中的一些常见查询函数的用法和示例。
1. 聚合函数聚合函数是一种用于计算数据集合中的总数、平均值、最小值、最大值和总和等统计数据的函数。
SQL Server提供了几种常见的聚合函数,包括SUM、AVG、MIN、MAX和COUNT。
- SUM函数:用于计算某一列的总和。
例如,我们可以使用以下查询来计算销售表中所有订单的总销售额:SELECT SUM(销售额) AS 总销售额FROM 销售表;- AVG函数:用于计算某一列的平均值。
例如,我们可以使用以下查询来计算所有产品的平均价格:SELECT AVG(价格) AS 平均价格FROM 产品表;- MIN函数:用于计算某一列的最小值。
例如,我们可以使用以下查询来查找销售表中最低销售额的订单:SELECT MIN(销售额) AS 最低销售额FROM 销售表;- MAX函数:用于计算某一列的最大值。
例如,我们可以使用以下查询来查找销售表中最高销售额的订单:SELECT MAX(销售额) AS 最高销售额FROM 销售表;- COUNT函数:用于计算某一列的行数。
例如,我们可以使用以下查询来计算产品表中的产品数量:SELECT COUNT(*) AS 产品数量FROM 产品表;2. 字符串函数字符串函数用于处理和操作字符串类型的数据。
SQL Server提供了一些常用的字符串函数,包括CONCAT、SUBSTRING、LEN和UPPER/LOWER。
- CONCAT函数:用于将多个字符串连接在一起。
例如,我们可以使用以下查询来将名字和姓氏连接成一个完整的姓名:SELECT CONCAT(名字, ' ', 姓氏) AS 全名FROM 员工表;- SUBSTRING函数:用于提取字符串的子串。
sql 同比 环比案例题
sql 同比环比案例题【原创版】目录1.SQL 概述2.同比和环比的定义及计算方法3.SQL 中同比和环比的案例题解析正文1.SQL 概述SQL(Structured Query Language,结构化查询语言)是一种用于管理关系型数据库的编程语言。
它可以用于查询、插入、更新和删除数据库中的数据,还可以用于创建和管理数据库表、视图和索引等。
SQL 具有丰富的功能和高度的灵活性,广泛应用于各种数据库管理系统,如 MySQL、Oracle、SQL Server 等。
2.同比和环比的定义及计算方法同比,是指将本期数据与历史同一时期的数据进行对比。
它可以用来衡量数据的变化情况,以及分析数据变化的原因。
同比的计算方法是:(本期数 - 同期数)/ 同期数。
环比,是指将本期数据与上期数据进行对比。
环比主要用于分析数据在相邻时期的变化趋势,以及判断数据的波动是否合理。
环比的计算方法是:(本期数 - 上期数)/ 上期数。
3.SQL 中同比和环比的案例题解析假设有一个销售数据表(sales_data),包含以下字段:date(日期)、sales(销售额)。
现在需要编写一个 SQL 查询,分别求出销售额的同比和环比增长率。
(1)同比增长率同比增长率的计算公式为:(本期销售额 - 同期销售额)/ 同期销售额。
因此,我们需要先找到去年同期的销售额,然后计算同比增长率。
以下是 SQL 查询语句:```sqlSELECTdate,sales,(sales - LAG(sales) OVER (PARTITION BY date ORDER BY date)) / LAG(sales) OVER (PARTITION BY date ORDER BY date) AS yoy FROMsales_data;```(2)环比增长率环比增长率的计算公式为:(本期销售额 - 上期销售额)/ 上期销售额。
因此,我们需要先找到上期的销售额,然后计算环比增长率。
SQL Server数据查询基础教程及界面介绍
SQL Server数据查询基础教程及界面介绍随着数据量的不断增长,对数据库进行高效的查询变得越来越重要。
SQL Server是一种关系型数据库管理系统(RDBMS),为用户提供了强大的数据查询功能。
本教程将介绍SQL Server的基本查询语句以及其界面的使用方法,帮助读者快速上手并提高数据查询和管理的效率。
一、SQL Server基本查询语句1. SELECT语句SELECT语句用于从一个或多个表中检索数据。
它的基本语法如下:SELECT 列名FROM 表名WHERE 条件;其中,列名代表要返回的列,表名代表要查询的表,条件是可选的,用于筛选满足某些条件的数据。
2. WHERE语句WHERE语句用于从表中筛选满足指定条件的数据。
常见的条件运算符包括等于(=)、不等于(<>)、大于(>)、小于(<)、大于等于(>=)、小于等于(<=)等。
例如,要查询员工表中工资大于5000的员工信息,可以使用如下语句:SELECT *FROM 员工表WHERE 工资 > 5000;3. ORDER BY语句ORDER BY语句用于对查询结果进行排序,默认按照升序排序。
可以通过在列名之后添加DESC关键字来实现降序排序。
例如,要按照工资从高到低排序查询员工表,可以使用如下语句:SELECT *FROM 员工表ORDER BY 工资 DESC;二、SQL Server界面介绍1. SQL Server Management Studio (SSMS)SQL Server Management Studio是SQL Server的官方集成开发环境(IDE),提供了丰富的功能和工具,用于管理和查询数据库。
它具有直观的用户界面,方便用户进行操作。
在SSMS中,用户可以通过“查询编辑器”编写和执行SQL查询语句。
在查询编辑器中,用户可以通过键入或粘贴SQL查询语句来执行查询。
执行结果将显示在“结果窗格”中,用户可以查看和分析查询结果。
sqlserver数据比对语句
sqlserver数据比对语句SQL Server是一种常用的关系型数据库管理系统(RDBMS),在进行数据比对时,我们可以使用一些特定的语句来实现。
下面列举了一些常用的SQL Server数据比对语句,希望对您有所帮助。
1. 使用INNER JOIN进行表间比对INNER JOIN是一种常用的连接操作,可以用于比对两个表中的数据。
比如,我们有两个表A和B,它们都有一个共同的字段ID,我们可以使用INNER JOIN将两个表中ID相同的记录进行比对,找出匹配的记录。
```sqlSELECT A.*, B.*FROM TableA AINNER JOIN TableB B ON A.ID = B.ID```2. 使用LEFT JOIN进行表间比对LEFT JOIN也是一种连接操作,它可以找出左表中的所有记录,同时将右表中与左表匹配的记录一并返回。
如果右表中的记录没有匹配的,则返回NULL值。
```sqlSELECT A.*, B.*LEFT JOIN TableB B ON A.ID = B.IDWHERE B.ID IS NULL```3. 使用EXCEPT进行表内比对EXCEPT操作可以找出两个表的差异,返回在第一个表中存在但第二个表中不存在的记录。
这个操作通常用于比对两个表的数据是否完全一致。
```sqlSELECT *FROM TableAEXCEPTSELECT *FROM TableB```4. 使用INTERSECT进行表内比对INTERSECT操作可以找出两个表中相同的记录,返回在两个表中都存在的记录。
这个操作通常用于比对两个表的数据是否完全一致。
```sqlSELECT *INTERSECTSELECT *FROM TableB```5. 使用COUNT进行记录数比对COUNT函数可以用于统计记录数,通过比对两个表的记录数是否相等,可以判断两个表的数据是否一致。
```sqlSELECT COUNT(*) AS CountAFROM TableASELECT COUNT(*) AS CountBFROM TableB-- 比对记录数IF (SELECT CountA FROM TableA) = (SELECT CountB FROM TableB) PRINT 'The records are the same'ELSEPRINT 'The records are different'```6. 使用SUM进行数值比对SUM函数可以用于计算某一列的总和,通过比对两个表中某一列的总和是否相等,可以判断两个表的数据是否一致。
SQL语句实现环比的计算
VW SOCRE4 —
Select StudentNo,StudentName,Subject,KS Q,ScoreChange,
Case ScoreChan ge Wh en 一3then ‘RED ’ Wh en一2then ‘YELLOW ’ Else ‘NORM AL’
2 应 用 背 景 介 绍
F rom V W SC O R E l g rouP bY
—
StudentNo,Subject
VW SOCRE 3
—
Select StudentNo,StudentName,Subject,KS Q,Score,
Case Wh en SCORE>SCOREl then 1
W hen SCORE<SCOREl then-1
VW SCORE1;
_
过 程 五 : 对 视 图 Vw sCORE1按 StudentNo、Subject分 组 , 对 同 学 号 同 课 目的 记 录 进 行 汇 总 ,得 到 同时 含 有 本 次 成 绩 Score、 上 次 成 绩 Score1、 上 2次 成 绩 Score2、 上 3次 成 绩 Score3 的 视 图 Vw
4 SOL语 句 编 写
F r O m V W S C O R E 3 W h e r e
—
ScoreChange<=-2
5 过 程 归 纳
及 以 上 亮 红 灯 。 收 集 学 生 各 次 考 试 成 绩 单 , 导入 TB
SCORE (学 生 成 绩 表 ) 中 , 包 括 字 段 StudentNo (学 号 ) 、StudentName (姓 名 ) 、 KSQ (考 试期编号 )、Subject(考试科 目)及 Score(成绩 )。其 中考试 期编 号按年 号及 考 试顺序号 设立 ,如 201501表 示 2015年第一次 考试 。在本例 中,实现 的 目标 就是根据考试期 编号 ,按学号 、考试科 目过滤 出成绩 连续 2次 (黄灯 )和 3次及 3次以上 (红灯 )下滑的数据
sql查询比例语句
sql查询比例语句
SQL查询比例语句是一种通过计算某个属性值在总数中所占的比例来进行查询的语句。
这种语句可以帮助我们深入了解数据分布情况,从而更好地进行数据分析和决策。
在SQL中,我们可以使用以下语句来查询某个属性值在总数中所占的比例:
SELECT COUNT(*) * 1.0 / (SELECT COUNT(*) FROM table_name) AS proportion
FROM table_name
WHERE attribute_name = 'attribute_value';
其中,COUNT(*)是计算出指定属性值在表中出现的次数,而(SELECT COUNT(*) FROM table_name)则是计算出表中总共有多少行
数据,最后将两个值相除即可得到所占比例。
需要注意的是,为了避免整数除法造成的精度损失,我们需要将其中一个操作数转换成浮点数,这里使用了* 1.0来实现。
除了上述语句,我们还可以使用GROUP BY语句来查询不同属性
值分别在总数中所占的比例,例如:
SELECT attribute_name, COUNT(*) * 1.0 / (SELECT COUNT(*) FROM table_name) AS proportion
FROM table_name
GROUP BY attribute_name;
这样可以帮助我们更全面地了解不同属性值之间的分布情况。
sqlserver获取同比或环比
sqlserver获取同⽐或环⽐⼀、要求1、表结构如下:ID DepartName(部门) Sales(销售量) SalesDate(销售⽇期)1 营销⼀部 300 2006-7-12 营销⼆部 500 2006-7-13 营销三部 800 2006-8-14 营销⼀部 600 2006-8-15 营销⼆部 800 2006-8-16 营销⼀部 400 2007-7-17 营销⼆部 800 2007-7-18 营销三部 700 2007-8-19 营销⼀部 600 2008-7-110 营销⼆部 300 2008-7-12、要根据要求得到以下数据1)得到同⽐数据部门对⽐年⽉本⽉销售总量去年同期销售总量同⽐营销⼀部 2006-07-01 300.00 NULL ⽆穷⼤营销⼆部 2006-07-01 500.00 NULL ⽆穷⼤营销三部 2006-08-01 800.00 NULL ⽆穷⼤营销⼀部 2006-08-01 600.00 NULL ⽆穷⼤营销⼆部 2006-08-01 800.00 NULL ⽆穷⼤营销⼀部 2007-07-01 400.00 300.00 33.33%营销⼆部 2007-07-01 800.00 500.00 60.00%营销三部 2007-08-01 700.00 800.00 -12.50%营销⼀部 2008-07-01 600.00 400.00 50.00%营销⼆部 2008-07-01 700.00 800.00 -12.50%(2)选择⽉份获取环⽐数据部门对⽐年⽉本⽉销售总量上⽉销售总量环⽐营销⼀部 2006-07-01 300.00 NULL ⽆穷⼤营销⼆部 2006-07-01 500.00 NULL ⽆穷⼤营销三部 2006-08-01 800.00 NULL ⽆穷⼤营销⼀部 2006-08-01 600.00 300.00 100.00%营销⼆部 2006-08-01 800.00 500.00 60.00%营销⼀部 2007-07-01 400.00 NULL ⽆穷⼤营销⼆部 2007-07-01 800.00 NULL ⽆穷⼤营销三部 2007-08-01 700.00 NULL ⽆穷⼤营销⼀部 2008-07-01 600.00 NULL ⽆穷⼤营销⼆部 2008-07-01 700.00 NULL ⽆穷⼤⼆、代码:1、创建表CREATE TABLE SalesDetail(ID int, --序号DepartName varchar(50), --部门Sales decimal(10,2), --销售量SalesDate Datetime --销售⽇期)2、插⼊测试数据insert into SalesDetail(ID, DepartName, Sales, SalesDate)select 1, '营销⼀部', 300, '2006-7-1'UNION ALL select 2, '营销⼆部', 500, '2006-7-1'UNION ALL select 3, '营销三部', 800, '2006-8-1'UNION ALL select 4, '营销⼀部', 600, '2006-8-1'UNION ALL select 5, '营销⼆部', 800, '2006-8-1'UNION ALL select 6, '营销⼀部', 400, '2007-7-1'UNION ALL select 7, '营销⼆部', 800, '2007-7-1'UNION ALL select 8, '营销三部', 700, '2007-8-1'UNION ALL select 9, '营销⼀部', 600, '2008-7-1'UNION ALL select 10, '营销⼆部', 700, '2008-7-1'3、实现SQL代码//得到环⽐select c.DepartName as 部门, convert(varchar(10), c.SalesDate, 23) as 对⽐年⽉, c.Sales as 本⽉销售总量, d.Sales as 上⽉销售总量, case when d.Sales is null or d.Sales=0 then '⽆穷⼤' else cast(cast((isnull(c.Sales, 0)-isnull(d.Sales,0))*100/isnull(d.Sales, 0) as decimal(10,2)) as varchar(50))+'%' end as 环⽐ from SalesDetail c left join(select a.DepartName as DepartName, a.Sales as Sales, a.SalesDate as lsSalesDate, b.SalesDate as SalesDate from SalesDetail a joinSalesDetail b on a.SalesDate=DateAdd(month, -1, b.SalesDate) and a.DepartName=b.DepartName) don c.SalesDate=d.SalesDate and c.DepartName=d.DepartName//得到同⽐select c.DepartName as 部门, convert(varchar(10), c.SalesDate, 23) as 对⽐年⽉, c.Sales as 本⽉销售总量, d.Sales as 去年同期销售总量, case when d.Sales is null or d.Sales=0 then '⽆穷⼤' else cast(cast((isnull(c.Sales, 0)-isnull(d.Sales,0))*100/isnull(d.Sales, 0) as decimal(10,2)) as varchar(50))+'%' end as 同⽐ from SalesDetail c left join(select a.DepartName as DepartName, a.Sales as Sales, a.SalesDate as lsSalesDate, b.SalesDate as SalesDate from SalesDetail a join SalesDetail b on a.SalesDate=DateAdd(year, -1, b.SalesDate) and a.DepartName=b.DepartName) don c.SalesDate=d.SalesDate and c.DepartName=d.DepartName4、SQL语句说明//获取根据时间获取去年同期时间select DateAdd(year, -1, SalesDate)//获取根据时间获取上⽉时间select DateAdd(month, -1, SalesDate)//获取根据时间获取去年同期时间数据select a.DepartName as DepartName, a.Sales as Sales, a.SalesDate as lsSalesDate, b.SalesDate as SalesDate from SalesDetail a join SalesDetail b on a.SalesDate=DateAdd(year, -1, b.SalesDate) and a.DepartName=b.DepartName//获取根据时间获取上⽉时间数据select a.DepartName as DepartName, a.Sales as Sales, a.SalesDate as lsSalesDate, b.SalesDate as SalesDate from SalesDetail a join SalesDetail b on a.SalesDate=DateAdd(month, -1, b.SalesDate) and a.DepartName=b.DepartName。
sql server中表查询的命令式
sql server中表查询的命令式在使用SQLServer进行表查询时,需要掌握一些命令,以便能够有效地检索数据。
以下是一些常见的SQL Server表查询的命令: 1. SELECT语句:SELECT语句是最常用的命令,用于从表中选择数据。
可以使用SELECT语句来选择所有列或特定列,也可以使用WHERE子句来筛选数据。
2. FROM语句:FROM语句用于指定要从中检索数据的表。
可以在FROM子句中指定一个或多个表。
3. WHERE语句:WHERE语句用于筛选表中的数据。
可以使用运算符、比较运算符和逻辑运算符来指定筛选条件。
4. ORDER BY语句:ORDER BY语句用于对检索的数据进行排序。
可以指定一个或多个排序条件,也可以使用ASC或DESC关键字指定升序或降序排列。
5. GROUP BY语句:GROUP BY语句用于根据一个或多个列对数据进行分组。
可以使用聚合函数来计算每个组的统计数据。
6. HAVING语句:HAVING语句用于筛选分组后的数据。
可以使用运算符、比较运算符和逻辑运算符来指定筛选条件。
7. JOIN语句:JOIN语句用于将两个或多个表中的数据合并在一起。
可以使用INNER JOIN、LEFT JOIN、RIGHT JOIN和FULL OUTER JOIN等类型的JOIN。
8. UNION语句:UNION语句用于将两个或多个查询的结果集合并在一起。
可以使用UNION、UNION ALL、INTERSECT和EXCEPT等类型的UNION。
以上是一些常见的SQL Server表查询的命令,掌握了这些命令可以更加高效地检索数据。
sql server比例计算语句
sql server比例计算语句
在SQL Server中,可以使用比例计算语句来计算两个数值之间的
比例。
下面是一个示例:
```
SELECT (column1 * 100) / column2 AS ratio
FROM table_name;
```
在这个示例中,假设我们有一个表名为table_name,其中包含两
列column1和column2。
我们想要计算column1和column2之间的比例。
使用上述语句,我们将column1乘以100,然后除以column2,得到的
结果将作为ratio返回。
拓展:除了上面提到的比例计算语句,SQL Server还支持一些其
他的计算函数和表达式,可以用于计算数值之间的比例。
例如,可以
使用SUM函数计算总和,并使用CASE表达式实现条件逻辑。
下面是一
个拓展示例:
```
SELECT SUM(CASE WHEN column1 > column2 THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS ratio
FROM table_name;
```
在这个示例中,我们使用SUM函数和CASE表达式来计算column1大于column2的记录数,并将其乘以100.0再除以总记录数,得到的结果作为ratio返回。
这个语句实现了一个更复杂的比例计算逻辑。
SQL Server中的数据分析和报表制作技巧
SQL Server中的数据分析和报表制作技巧SQL Server是一款强大的关系型数据库管理系统,其拥有着丰富的数据分析和报表制作技巧。
通过使用SQL Server中提供的各种分析工具和函数,可以将海量数据转化为有用的信息,并提供可视化的报表,帮助企业进行决策和管理。
一、数据分析1. SQL Server Analysis Services(SSAS)SSAS是SQL Server中一款重要的分析工具,其主要功能包括多维数据分析和数据挖掘。
通过使用SSAS,可以将大量的数据拆分为多个数据维度,并构建多维数据模型,从而实现更好的数据分析和数据挖掘。
在对企业数据进行分析时,使用SSAS可以更快速、更准确地找到数据的关联和趋势,为企业决策提供有力的支持。
2. SQL Server Reporting Services(SSRS)SSRS是SQL Server中一款重要的报表制作工具,为企业提供了一套专业的报表制作和发布程序。
通过使用SSRS,可以将SQL Server中的数据转化为可视化的报表,并支持多种报表格式的输出,包括PDF、Word和Excel等。
此外,SSRS还支持数据参数化和安全性控制等高级功能,使企业用户更方便地控制数据和报表的生成和分发。
二、报表制作1. 数据参数化报表中常常需要对数据进行筛选和过滤,这就需要使用到数据参数化。
通过对报表数据的参数化,可以使报表的筛选条件更加灵活,也可以减少对数据库的冗余读取,提升系统的性能。
在SSRS中,可以使用参数化查询和嵌入式数据参数等方式来实现数据参数化,从而更好地控制报表数据的生成和展示。
2. 数据绑定数据绑定是报表制作的重要环节,通过将报表控件与数据源进行绑定,可以使报表数据的展示更加灵活和高效。
在SSRS中,可以通过使用数据集和数据源等相关功能,实现报表控件与SQL Server中数据的绑定,从而达到报表制作的高效、便捷和灵活性。
3. 报表布局报表布局是报表制作中的重要环节,通过合理的布局设置,可以使报表的展示更加美观、易读和易用。
sqlserver 百分比计算
sqlserver 百分比计算
在SQL Server中,可以使用百分比计算来实现各种功能,比如计算增长率、比较不同组的百分比等。
以下是一些常见的百分比计算方法:
1. 计算增长率:
如果你想计算某个数值的增长率,可以使用以下公式:
增长率 = (当前值上期值) / 上期值 100。
在SQL Server中,你可以使用这个公式来计算增长率,例如:
SELECT ((当前值上期值) / 上期值) 100 AS 增长率。
FROM 表名。
2. 计算百分比比例:
如果你想计算某个数值在总数中的百分比比例,可以使用以
下公式:
百分比 = (某个数值 / 总数) 100。
在SQL Server中,你可以使用这个公式来计算百分比比例,例如:
SELECT (某个数值 / 总数) 100 AS 百分比。
FROM 表名。
3. 计算分组内的百分比:
如果你想计算某个分组内各个项目的百分比比例,可以使用
窗口函数来实现,例如:
SELECT 项目名称, 数值, 数值 / SUM(数值) OVER (PARTITION BY 分组字段) 100 AS 百分比。
FROM 表名。
以上是一些在SQL Server中常见的百分比计算方法,通过这些方法你可以实现各种百分比计算需求。
当然,在实际应用中,你可能需要根据具体的情况来选择合适的计算方法,并且在编写SQL语句时要注意数据类型的转换和异常值的处理,以确保计算结果的准确性。
希望这些信息能够帮助到你。
sqlserver计算同比,环比增长
sqlserver计算同⽐,环⽐增长/****** Script for SelectTopNRows command from SSMS ******/SELECT[fdSequenceID],[fdInnerTime],[fdTime],[fdData],[fdState],[fdUpdateTime],[fdCreateTime]FROM[NewDBTest].[dbo].[tbDataMonthHG]WITH f AS(SELECT ROW_NUMBER()OVER( partition by fdSequenceID ORDER BY fdTime) AS id, *FROM[NewDBTest].[dbo].[tbDataMonthHG])select t.*,fdRate=(cast(cast(100*((t.fdData/NULLif(d.fdData,0))-1) as numeric(25,10)) as varchar(50))+'%' ) --⼩数变百分数from f tleft join f d ont.fdInnerTime =DateAdd(year,1,d.fdInnerTime) and t.fdSequenceID = d.fdSequenceID --同⽐增长order by fdSequenceID,id asc环⽐增长:WITH f AS(SELECT ROW_NUMBER()OVER( partition by fdSequenceID ORDER BY fdTime) AS id, *FROM[NewDBTest].[dbo].[tbDataMonthHG]where fdSequenceID <100 )select t.*,fdRate=(cast(cast(100*((t.fdData/NULLif(d.fdData,0))-1) as numeric(25,10)) as varchar(50))+'%' ) --将分数变为百分数from f tleft join f d ont.fdInnerTime =DateAdd(month,1,d.fdInnerTime) and t.fdSequenceID = d.fdSequenceID --获取根据时间获取上⽉时间order by fdSequenceID,id asc某⼀时间点与相邻的上⼀个时间的增长WITH f AS(SELECT ROW_NUMBER()OVER( partition by fdSequenceID ORDER BY fdTime) AS id, *FROM[NewDBTest].[dbo].[tbData])SELECTt.fdSequenceID,t.fdInnerTime,t.fdTime,t.fdData,t.fdState,t.fdUpdateTime,t.fdCreateTime,t.id,(select cast(cast(100*((t.fdData/NULLif(d.fdData,0))-1) as numeric(35,10)) as varchar(50))+'%') AS fdRatefrom f tLEFT JOIN f d on t.id=d.id+1where t.fdSequenceID = d.fdSequenceID ORDER by t.fdSequenceID ASC-- 不会返回nullWITH f AS(SELECT ROW_NUMBER()OVER( partition by fdSequenceID ORDER BY fdTime) AS id, *FROM[NewDBTest].[dbo].[tbData]where fdSequenceID<188)select t.*,cast(cast(100*((t.fdData/NULLif(d.fdData,0))-1) as numeric(25,10)) as varchar(50))+'%'from f tleft join f don datediff(day,DateAdd(day,d.id-1,DateAdd(month,d.fdSequenceID-1,'1900-1-1')),DateAdd(day,t.id-1,DateAdd(month,t.fdSequenceID-1,'1900-1-1'))) >0-- 会返回null。
SQL优化-同比计算
SQL优化-同⽐计算记录⼀次SQL优化, 在计算同⽐的时候. 就太久没有写语句了, 能⼒在逐渐下滑, 思维也是, 感觉还是有点可怕的. ⾃从转业务以来, 就基本没有碰过代码这⽅⾯了. 甚⾄连 SQL 都开始要搜索了. ⽽我⽇常更多是让专业的开发来做, 我负责跟进度, 也不知道我这样存在的意义是否有价值.正好⼜在弄BI, 然后呢根据过往经验, 处理逻辑还是尽量在后台处理好, 前台就直接展⽰即可.有这样⼀个基础的算同⽐的需求, 分为两步. ⼀个是要对某字段进⾏合并, 然后基于合并再进⾏汇总和计算同⽐. 我的 1.0 版本是这样的.1.0 临时表 + 2表连接⽤的是 Sql ServerWITH A AS (SELECTCASEWHEN AGENT IN ('AA', 'AAA') THEN 'AA'WHEN AGENT IN ('BB', 'BBB') THEN 'BB'WHEN AGENT IN ('CC', 'CCC') THEN 'CCC'ELSE AGENT END AS 代理, 品类, 销售时间, 数量FROM AAAAAWHERE 是否电商 = 1AND 品类 IN ('A品类', 'B品类', 'C品类'))-- MAIN-- 当⽉销量SELECTB.*, C.当⽉销量 AS 同期19⽉销FROM (SELECTA.代理, A.品类, SUM(A.数量) AS 当⽉销量FROM AWHERE 销售时间 >= DATEFROMPARTS(YEAR(GETDATE()),MONTH(GETDATE()), 1)AND 销售时间 <= GETDATE()GROUP BY 代理, 品类) AS B-- 19年同期销量LEFT JOIN (SELECT代理, 品类, SUM(数量) AS 当⽉销量FROM AWHERE 销售时间 >= DATEFROMPARTS(2019, MONTH(GETDATE()), 1)AND 销售时间 <= DATEFROMPARTS(2019, MONTH(GETDATE()), DAY(GETDATE())-1)GROUP BY 代理, 品类) AS CON B.代理 = C.代理 AND B.品类 = C.品类ORDER BY B.当⽉销量 DESC问题点为了处理⼀个字段, 建了个临时查询, 相等于遍历了⼀整个表算同⽐, ⽤到了 2个表 (当期, 同期) 进⾏拼接 (各⾃还执⾏了⼀次 group by )代码冗余, 结构不清晰对于计算同⽐这块, 其实结构是完全⼀样的, 只是时间不同⽽已, 那判断时间就可以了, 完全没必要⽤ Join 搞两张表.2.0 ⽤ Case when 时间代替表 Join 算同⽐WITH A AS (SELECTCASEWHEN AGENT IN ('AA', 'AAA') THEN 'AA'WHEN AGENT IN ('BB', 'BBB') THEN 'BB'WHEN AGENT IN ('CC', 'CCC') THEN 'CCC'ELSE AGENT END AS 代理, 品类, 销售时间, 数量FROM AAAAAWHERE 是否电商 = 1AND 品类 IN ('A品类', 'B品类', 'C品类'))-- MAINSELECT代理, 品类, SUM(CASE WHEN销售时间 BETWEEN DATEFROMPARTS(YEAR(GETDATE()),MONTH(GETDATE()), 1) AND GETDATE()THEN 数量 ELSE 0 END) AS 当⽉销量, SUM(CASE WHEN销售时间 BETWEEN DATEFROMPARTS(2019, MONTH(GETDATE()), 1) AND DATEFROMPARTS(2019, MONTH(GETDATE()), DAY(GETDATE())-1) THEN 数量 ELSE 0 END) AS 同期19年⽉销量FROM AGROUP BY 代理, 品类ORDER BY 当⽉销量 DESC问题点是减少了查询, 极⼤优化了, 但临时表也是不必要的, 可以⼀步到位.美中不⾜, 尚可再优化3.0 将 Case when 结合 Group By ⼀步到位sql server 很烦的⼀点是, 不能同级引⽤...SELECTCASEWHEN AGENT IN ('AA', 'AAA') THEN 'AA'WHEN AGENT IN ('BB', 'BBB') THEN 'BB'WHEN AGENT IN ('CC', 'CCC') THEN 'CCC'ELSE AGENT END AS 代理, 品类, SUM(CASE WHEN销售时间 BETWEEN DATEFROMPARTS(YEAR(GETDATE()),MONTH(GETDATE()), 1) AND GETDATE()THEN 数量 ELSE 0 END) AS 当⽉销量, SUM(CASE WHEN销售时间 BETWEEN DATEFROMPARTS(2019, MONTH(GETDATE()), 1) AND DATEFROMPARTS(2019, MONTH(GETDATE()), DAY(GETDATE())-1) THEN 数量 ELSE 0 END) AS 同期19年⽉销量FROM AAAAAWHERE 是否电商 = 1AND 品类 IN ('A品类', 'B品类', 'C品类')GROUP BY 品类, CASEWHEN AGENT IN ('AA', 'AAA') THEN 'AA'WHEN AGENT IN ('BB', 'BBB') THEN 'BB'WHEN AGENT IN ('CC', 'CCC') THEN 'CCC'ELSE AGENT ENDORDER BY 当⽉销量 DESC抽空还是要多练练, 这个很容易就忘掉了.。
同比环比sql实例
环比就是今年第n月与第n-1月或第n+1月比;同比就是今年第n月与去年第n月比。
建测试表,假设是个销售数量表:create table t (dt date,cnt number);随便插入些测试数据,最后表的内容如下:DT CNT---------- ----------2012-02-09 152012-02-21 22012-03-23 12012-03-23 52012-04-23 22012-05-12 202012-07-01 202012-07-21 20显示环比,如果某个月没有销售,就有点儿麻烦。
先想个办法,显示本年度的1至12月,有个很有技巧的技术来实现:SQL> set pagesize 20SQL> with m as (select '2012-'||lpad(rownum,2,'0') v from dual connect by level<=12)select * from m;V---------2012-012012-022012-032012-042012-052012-062012-072012-082012-092012-102012-112012-12接下来就容易了,两个表外连,使用lag统计函数就可以了。
with m as (select '2012-'||lpad(rownum,2,'0') v from dual connect by level<=12)select m.v "月份",nvl(sum(t),0) "销售数量",lag(nvl(sum(t),0),1) over (order by m.v) "上月销量数量",nvl(sum(t),0)-lag(nvl(sum(t),0),1) over (order by m.v) "环比增加量",round((case when nvl(sum(t),0)=0 then null else (nvl(sum(t),0)-lag(nvl(sum(t),0),1) over (order by m.v))/nvl(sum(t),0) end)*100,1) "环比增加比例(%)"from m left outer join ton m.v=to_char(t.dt,'yyyy-mm') group by m.v order by 1月份销售数量上月销量数量环比增加量环比增加比例(%)--------- ---------- ------------ ---------- ---------------2012-01 02012-02 17 0 17 1002012-03 6 17 -11 -183.32012-04 2 6 -4 -2002012-05 20 2 18 902012-06 0 20 -202012-07 40 0 40 1002012-08 0 40 -402012-09 0 0 02012-10 0 0 02012-11 0 0 02012-12 0 0 0---------------------------------------------------------------------------------------------------------------------------------- SELECT EMPLOYEENO,YEARMONTH,SALARY,MIN(SALARY)KEEP(DENSE_RANK FIRST ORDER BY YEARMONTH)OVER(PARTITION BY EMPLOYEENO) FIRST_SALARY -- 基比分析 salary/first_salary,LAG(SALARY,1,0)OVER(PARTITION BY EMPLOYEENO ORDER BY YEARMONTH)AS PREV_SAL -- 环比分析,与上个月份进行比较,LAG(SALARY,12,0)OVER(PARTITION BY EMPLOYEENO ORDER BY YEARMONTH)AS PREV_12_SAL -- 同比分析,与上个年度相同月份进行比较,SUM(SALARY)OVER(PARTITION BY EMPLOYEENO,SUBSTR(YEARMONTH,1,4)ORDER BY YEARMONTH RANGE UNBOUNDED PRECEDING) LJ --累计值FROM SALARYBYMONTHORDER BY EMPLOYEENO,YEARMONTH-。
sql同比环比计算
sql同⽐环⽐计算题⽬:有两个表表⼀:销售明细表⼆:产品明细需求:查询2020年,每⽉的销售额,以及同⽐环⽐,并按照年⽉进⾏升序排序思路:分步操作1. 获得每⽉的数据⾸先的抽取时间,以及获得每个⽉的销售额,要有销售额,两个表肯定是要连接起来的------- 获取时间YEAR(字段名)—获取年份MONTH(字段名)----获取时间SELECT YEAR(s.sail_time) 年, MONTH(s.sail_time) ⽉ , SUM(s.number*p.pro_price) 销售额FROM sail_info sLEFT JOIN produce_detail pON s.produce_id=p.produce_idGROUP BY YEAR(s.sail_time) , MONTH(s.sail_time)此处使⽤左连接的原因:是要补充销售表⾥单品的价格,要以左表为基准,要⽤了左连接结果:2. 单步操作获得同⽐数据同⽐:⼀般情况下是今年第n⽉与去年第n⽉⽐计算⽅式:同⽐增长率=(本期数-同期数)÷同期数×100%所以要有个本期数据与同期数据⼀⼀对应的表,那就要本期数据与同期数据分离有了第⼀步之后很容易获得数据本期数据:SELECT YEAR(s.sail_time) 年, MONTH(s.sail_time) ⽉ , SUM(s.number*p.pro_price) 销售额FROM sail_info sLEFT JOIN produce_detail pON s.produce_id=p.produce_idwhere YEAR(s.sail_time)=2020GROUP BY YEAR(s.sail_time) , MONTH(s.sail_time)同期数据:SELECT YEAR(s.sail_time) 年, MONTH(s.sail_time) ⽉ , SUM(s.number*p.pro_price) 销售额FROM sail_info sLEFT JOIN produce_detail pON s.produce_id=p.produce_idwhere YEAR(s.sail_time)=2019GROUP BY YEAR(s.sail_time) , MONTH(s.sail_time)下⾯就要进⾏表的关联了本期、同期的区别就是年份不⼀样,⽉份⼀样呗,那就⽤⽉份作为连接点进⾏连接,代码和结果截图如下,同⽐就完成了~计算的是本期,本期数据是关键所以这边进⾏的是右连接—因为本期数据放在右边,放左边⽤左连接就好了ps:如果觉得这边跳了步骤的话可以将查询结果改成 * 先去查看关联之后的表SELECT CONCAT(e,'-',a) 年⽉, b ⽉销售额,CASE WHEN d>0THEN CONCAT((b-d)/d*100,'%') -- 转化为百分⽐,此处考虑到销售额为0的情况,分母不能为0,⽤case进⾏了条件判断ELSE "同期没有数据" END同⽐-- 这边的⽂字可以换掉FROM(SELECT YEAR(s.sail_time) f , MONTH(s.sail_time) c , SUM(s.number*p.pro_price) d FROM sail_info s LEFT JOIN produce_detail pON s.produce_id=p.produce_id WHERE YEAR(s.sail_time)=2019GROUP BY MONTH(s.sail_time)) s2RIGHT JOIN(SELECT YEAR(s.sail_time) e,MONTH(s.sail_time) a , SUM(s.number*p.pro_price) b FROM sail_info s LEFT JOIN produce_detail pON s.produce_id=p.produce_id WHERE YEAR(s.sail_time)=2020GROUP BY MONTH(s.sail_time)) s1ON s1.a=s2.c3.单步操作获得环⽐数据环⽐:⼀般是指报告期⽔平与前⼀时期⽔平之⽐,此处指本⽉数据与上⽉数据计算⽅式:环⽐增长速度=(本期数-上期数)÷上期数×100%肯定也是要有表的关联了呗,怎么连呢???既然是计算2020年的环⽐,那就以要计算的为基础数据,进⾏表的关联上⾯已经有全部的年份、⽉份对应的数据,这⼀步主要是进⾏表的关联两个表进⾏关联:-1 2020年数据的表,即判断条件设置年份为2020的查询结果表-2 考虑到2020年⼀⽉份对应的是2019年的12⽉份,所以这个张表是不加判断条件的表,包含了2019年和2020年数据的表SELECT*FROM(SELECT YEAR(s.sail_time) e,MONTH(s.sail_time) a , SUM(s.number*p.pro_price) 本期销售额FROM sail_info s LEFT JOIN produce_detail pON s.produce_id=p.produce_id WHERE YEAR(s.sail_time)=2020GROUP BY MONTH(s.sail_time)) s1LEFT JOIN(SELECT YEAR(s.sail_time) f, MONTH(s.sail_time) g, SUM(s.number*p.pro_price) 上期销售额FROM sail_info s LEFT JOIN produce_detail pON s.produce_id=p.produce_id GROUP BY MONTH(s.sail_time),YEAR(s.sail_time)) s3ON ((s1.a-1)=s3.g AND s1.e=s3.f) OR (s1.a=1AND s3.g=12AND s3.f=2019)解析以下这个:(s1.a-1)=s3.g AND s1.e=s3.f这个是针对2020年2⽉份的数据,2020 02-06 的数据与2020 01-05的数据⼀⼀对应按关联前的,a(⽉份)和g(⽉份)应该是相等的,因为对⽐的是上⼀期的,所以要错开,⼤的减掉等与⼩的那⼀⽉份怎么办呢??s1.a=1AND s3.g=12AND s3.f=2019这边就不能⽤上⾯的办法了,跨年了,所以需要⽤and连接的⽅式进⾏限制,⽽且需要限定为2019年的12⽉份,这边因为数据⽐较少,不限定年份也没问题两个部分⽤ or 并列存在,两个条件要分别⽤括号括起来,否则这个查询条件等于没有。
在SQLServer中如何比较两个表的各组数据
在SQLServer中如何⽐较两个表的各组数据开始前⼀阵⼦,在项⽬中碰到这样⼀个SQL查询需求,有两个相同结构的表(table_left & table_right),如下:图1.检查表table_left的各组(groupId),是否在表table_right中存在有⼀组(groupId)数据(data)与它的数据(data)完全相等.如图1. 可以看出表table_left和table_right存在两组数据完整相等:图2.分析从上⾯的两个表,可以知道它们存放的是⼀组⼀组的数据;那么,接下来我借助数学集合的列举法和运算进⾏分析。
先通过集合的列举法描述两个表的各组数据:图3.这⾥只有两种情况,相等和不相等。
对于不相等,可再分为部分相等、包含、和完全不相等。
使⽤集合描述,可使⽤交集,⼦集,并集。
如下⾯图4.,我列举出这⼏种常见的情况:图4.实现在数据库中,要找出表table_left和表table_right存在相同数据的组,⽅法很多,这⾥我列出两种常⽤的⽅法。
(下⾯的SQL脚本,是以图4.的数据为基础参考)⽅法1:通过"Select … From …Order by … xml for path('') "把各组的data列数据连串起来(如,图4.把table_left的组#11的列data连串起来成"data1-data2-data3"),其他分组(包含表table_right)以此⽅法实现data列数据连串起来;然后通过⽐较两表的连串后字段是否存在相等,若是相等就说明这⽐较多两组数据相等,由此可以判断出表table_left的哪组数据在表table_right存在与它数据完全相等的组。
针对⽅法1,需要对原表增加⼀个字段dataPath,⽤于存储data列数据连串的结果,如:alter table table_left add dataPath nvarchar(200)alter table table_right add dataPath nvarchar(200)分组连串data列数据并update⾄刚新增的列dataPath,如:update aset dataPath=b.dataPathfrom table_left across apply(select (select'-'+x.data from table_left x where x.groupId=a.groupId order by x.data for xml path(''))as dataPath)bupdate aset dataPath=b.dataPathfrom table_right across apply(select (select'-'+x.data from table_right x where x.groupId=a.groupId order by x.data for xml path(''))as dataPath)b接下来就是查询了,如:select distinct a.groupIdfrom table_left awhere exists(select 1 from table_right x where x.dataPath=a.dataPath)完整代码:View Codeuse tempdbgoif object_id('table_left') is not null drop table table_leftif object_id('table_right') is not null drop table table_rightgocreate table table_left(groupId nvarchar(5),data nvarchar(10))create table table_right(groupId nvarchar(5),data nvarchar(10))goalter table table_left add dataPath nvarchar(200)alter table table_right add dataPath nvarchar(200)gocreate nonclustered index ix_left on table_left(dataPath)create nonclustered index ix_right on table_right(dataPath)goset nocount ongoinsert into table_right(groupId,data)select'#1','data1'union allselect'#1','data2'union allselect'#1','data3'union allselect'#2','data55'union allselect'#2','data55'union allselect'#3','data91'union allselect'#3','data92'union allselect'#4','data65'union allselect'#4','data66'union allselect'#4','data67'union allselect'#4','data68'union allselect'#4','data69'union allselect'#5','data77'union allselect'#5','data79'insert into table_left(groupId,data)select'#11','data1'union allselect'#11','data2'union allselect'#11','data3'union allselect'#22','data55'union allselect'#22','data57'union allselect'#33','data99'union allselect'#33','data99'union allselect'#44','data66'union allselect'#44','data68'union allselect'#55','data77'union allselect'#55','data78'union allselect'#55','data79'goupdate aset dataPath=b.dataPathfrom table_left across apply(select (select'-'+x.data from table_left x where x.groupId=a.groupId order by x.data for xml path('')) as dataPath)bupdate aset dataPath=b.dataPathfrom table_right across apply(select (select'-'+x.data from table_right x where x.groupId=a.groupId order by x.data for xml path('')) as dataPath)b--select distinct a.groupIdfrom table_left awhere exists(select1from table_right x where x.dataPath=a.dataPath)⽅法2:通过SQL Sever提供的集运算符"Except",判断两组⾮重复的数据。
sqlserver 环比上年计算公式
在SQL Server中,可以使用以下公式计算环比和同比增长率:环比增长率(MoM)= (当前期数值- 上一期数值) / 上一期数值* 100同比增长率(YoY)= (当前期数值- 同期去年数值) / 同期去年数值* 100其中,当前期数值是指当前时间段的数值,上一期数值是指上一个时间段的数值,同期去年数值是指去年同一个时间段的数值。
假设有一个销售数据表SalesTable,其中包含时间周期和销售数量字段。
以下是一个示例查询,计算销售数量的环比和同比增长率:-- 环比增长率查询SELECTCurrentPeriod.SalesQuantity AS CurrentPeriodSales,PreviousPeriod.SalesQuantity AS PreviousPeriodSales,(CurrentPeriod.SalesQuantity - PreviousPeriod.SalesQuantity) / PreviousPeriod.SalesQuantity * 100 AS MoM_Growth FROMSalesTable AS CurrentPeriodINNER JOINSalesTable AS PreviousPeriodON CurrentPeriod.TimePeriod = DATEADD(MONTH, -1, PreviousPeriod.TimePeriod) -- 假设时间周期为月份-- 同比增长率查询SELECTCurrentPeriod.SalesQuantity AS CurrentPeriodSales,YearAgoPeriod.SalesQuantity AS YearAgoPeriodSales,(CurrentPeriod.SalesQuantity - YearAgoPeriod.SalesQuantity) / YearAgoPeriod.SalesQuantity * 100 AS YoY_GrowthFROMSalesTable AS CurrentPeriodINNER JOINSalesTable AS YearAgoPeriodON CurrentPeriod.TimePeriod = DATEADD(YEAR, -1, YearAgoPeriod.TimePeriod) -- 假设时间周期为年份以上示例仅为参考,实际查询需要根据具体的表结构和需求进行调整。
SQL实现占比同比环比指标分析
SQL实现占比同比环比指标分析SQL是一种用于关系型数据库管理系统的查询语言,它可以用于实现占比、同比和环比指标分析。
在本文中,我将介绍如何使用SQL实现这些指标分析。
占比分析是通过计算一个元素相对于总体的百分比来衡量其重要性。
在SQL中,我们可以使用聚合函数来计算占比。
以下是一个示例SQL查询,用于计算一些元素在总体中的占比:```SELECT (COUNT(*) / (SELECT COUNT(*) FROM table)) * 100 AS proportionFROM tableWHERE condition;```在上述查询中,我们首先通过子查询获得总体的数量,然后用条件过滤数据并计算满足条件的记录数量。
最后,我们将满足条件的记录数量除以总体数量,并将结果乘以100,得到占比。
同比分析是比较两个时间段之间的数据变化。
在SQL中,我们可以使用窗口函数来实现同比分析。
以下是一个示例SQL查询,用于计算一些指标在两个时间段内的同比变化率:```SELECT date, value, LAG(value) OVER (ORDER BY date) AS previous_value,(value - LAG(value) OVER (ORDER BY date)) / LAG(value) OVER (ORDER BY date) * 100 AS YoY_growthFROM tableWHERE condition;```在上述查询中,我们使用LAG函数获取前一个时间段(上一年)的数据值。
然后,我们计算两个时间段之间的变化率,并将结果乘以100,得到同比变化率。
环比分析是比较两个相邻时间段之间的数据变化。
与同比分析类似,我们也可以使用窗口函数来实现环比分析。
以下是一个示例SQL查询,用于计算一些指标在两个相邻时间段内的环比变化率:```SELECT date, value, LAG(value) OVER (ORDER BY date) AS previous_value,(value - LAG(value) OVER (ORDER BY date)) / LAG(value) OVER (ORDER BY date) * 100 AS MoM_growthFROM tableWHERE condition;```在上述查询中,我们同样使用LAG函数获取前一个时间段(上一个月)的数据值。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
SQL报表同比与环比查询在做报表时用到SQL同比与环比查询。
先来看下表结构如下:
要根据要求得到以下数据
1)选择开始年月,结束年月,得到同比数据
eg.开始年月:2006-7 结束:2006-8
获取:
(2)选择月份获取环比数据
eg.选择2008.7
--雇员数据
CREATE TABLE Employee(
ID int, --雇员编号(主键)
Name nvarchar(10), --雇员名称
Deptnvarchar(10)) --所属部门
INSERT Employee SELECT 1,N'张三',N'大客户部'
UNION ALL SELECT 2,N'李四',N'大客户部'
UNION ALL SELECT 3,N'王五',N'销售一部'
--费用表
CREATE TABLE Expenses(
EmployeeIDint, --雇员编号
Date Datetime, --发生日期
Expenses nvarchar(10), --指标名称
[Money] decimal(10,2)) --发生金额
INSERT Expenses SELECT 1,'2004-01-01',N'销售',100
UNION ALL SELECT 1,'2004-01-02',N'销售',150
UNION ALL SELECT 1,'2004-12-01',N'销售',200
UNION ALL SELECT 1,'2005-01-10',N'销售', 80
UNION ALL SELECT 1,'2005-01-15',N'销售', 90
UNION ALL SELECT 1,'2005-01-21',N'成本', 8
UNION ALL SELECT 2,'2004-12-01',N'成本', 2
UNION ALL SELECT 2,'2005-01-10',N'销售', 10
UNION ALL SELECT 2,'2005-01-15',N'销售', 40
UNION ALL SELECT 2,'2005-01-21',N'成本', 8
UNION ALL SELECT 3,'2004-01-01',N'销售',200
UNION ALL SELECT 3,'2004-12-10',N'销售', 80
UNION ALL SELECT 3,'2005-01-15',N'销售', 90
UNION ALL SELECT 3,'2005-01-21',N'销售', 8
GO
--统计
DECLARE @Period char(6)
SET @Period='200501' --统计的年月
--统计处理
DECLARE @Last_Periodchar(6),@Previous_Period char(6)
SELECT @Last_Period=CONVERT(char(6),DATEADD(Year,-1,@Period+'01'),112), @Previous_Period=CONVERT(char(6),DATEADD(Month,-1,@Period+'01'),112)
SELECT Dept,Expenses,Name,
C_Money,
L_Money,
L_UP=C_Money-L_Money,
L_Prec=CASE
WHEN L_Money=0 THEN '----'
ELSE SUBSTRING('↓-↑',CAST(SIGN(C_Money-L_Money) as int)+2,1)
+CAST(CAST(ABS(C_Money-L_Money)*100/P_Money as decimal(10,2)) as varchar)+'%'
END,
P_Money,
P_UP=C_Money-P_Money,
P_Prec=CASE
WHEN P_Money=0 THEN '----'
ELSE SUBSTRING('↓-↑',CAST(SIGN(C_Money-P_Money) as int)+2,1)
+CAST(CAST(ABS(C_Money-P_Money)*100/P_Money as decimal(10,2)) as varchar)+'%'
END
FROM(
SELECT a.Dept,b.Expenses,
Name=CASE WHEN GROUPING(Name)=1 THEN '<合计>' ELSE END,
C_Money=ISNULL(SUM(CASE CONVERT(char(6),b.Date,112) WHEN @Period THEN b.[Money] END),0),
L_Money=ISNULL(SUM(CASE CONVERT(char(6),b.Date,112) WHEN @Last_Period THEN b.[Money] END),0),
P_Money=ISNULL(SUM(CASE CONVERT(char(6),b.Date,112) WHEN @Previous_Period THEN b.[Money] END),0)
FROM Employee a,Expenses b
WHERE a.ID=b.EmployeeID
AND CONVERT(char(6),b.Date,112) IN(@Last_Period,@Previous_Period,@Period) GROUP BY a.Dept,b.Expenses,a.ID, WITH ROLLUP
HAVING (GROUPING()=0 OR GROUPING(a.ID)=1)
AND (GROUPING(a.ID)=0 OR GROUPING(b.Expenses)=0))a
/**//*--结果。