发布网友 发布时间:2022-04-08 17:55
共3个回答
懂视网 时间:2022-04-08 22:17
ProductGUID,type,typecode, MAX(CASE YearMonth WHEN ‘9999-13‘ THEN val ELSE 0 END) AS ‘项目合计‘, MAX(CASE YearMonth WHEN @Year+‘-00‘ THEN val ELSE 0 END) AS ‘以前年度合计‘, MAX(CASE YearMonth WHEN @Year+‘-13‘ THEN val ELSE 0 END) AS ‘2011年合计‘, MAX(CASE YearMonth WHEN @Year+‘-01‘ THEN val ELSE 0 END) AS ‘2011-01‘, MAX(CASE YearMonth WHEN @Year+‘-02‘ THEN val ELSE 0 END) AS ‘2011-02‘, MAX(CASE YearMonth WHEN @Year+‘-03‘ THEN val ELSE 0 END) AS ‘2011-03‘, MAX(CASE YearMonth WHEN @Year+‘-04‘ THEN val ELSE 0 END) AS ‘2011-04‘, MAX(CASE YearMonth WHEN @Year+‘-05‘ THEN val ELSE 0 END) AS ‘2011-05‘, MAX(CASE YearMonth WHEN @Year+‘-06‘ THEN val ELSE 0 END) AS ‘2011-06‘, MAX(CASE YearMonth WHEN @Year+‘-07‘ THEN val ELSE 0 END) AS ‘2011-07‘, MAX(CASE YearMonth WHEN @Year+‘-08‘ THEN val ELSE 0 END) AS ‘2011-08‘, MAX(CASE YearMonth WHEN @Year+‘-09‘ THEN val ELSE 0 END) AS ‘2011-09‘, MAX(CASE YearMonth WHEN @Year+‘-10‘ THEN val ELSE 0 END) AS ‘2011-10‘, MAX(CASE YearMonth WHEN @Year+‘-11‘ THEN val ELSE 0 END) AS ‘2011-11‘, MAX(CASE YearMonth WHEN @Year+‘-12‘ THEN val ELSE 0 END) AS ‘2011-12‘, MAX(CASE YearMonth WHEN ‘9999-12‘ THEN val ELSE 0 END) AS ‘以后年度合计‘ into #tempSaleDtl3 FROM #tempSaleDtl2 GROUP BY ProductGUID,type,typecode ORDER BY ProductGUID,typecode
来看看这里的数据与前一步的对应关系:
结果部分数据如图:
其中列名为了显示方便,这里用了2011,可以将列名变了year-01……。
关于行转列的知识前系列也提过,不理解的请自觉前去复习。
小技巧是用到了MAX聚合,关于这点前面聚合的文章中有提到。整个的数据结构现在越来越趋近于最后的结果了,year~继续。
来看看结果中还差什么?项目!
这里用 “--”来代替数据:
--从Project表中加入项目数据select ProjectName as orderCode,ProjectGUID,ProjectName, ‘--‘ AS ‘项目合计‘, ‘--‘ AS ‘以前年度合计‘, ‘--‘ AS ‘2011年合计‘, ‘--‘ AS ‘2011-01‘, ‘--‘ AS ‘2011-02‘, ‘--‘ AS ‘2011-03‘, ‘--‘ AS ‘2011-04‘, ‘--‘ AS ‘2011-05‘, ‘--‘ AS ‘2011-06‘, ‘--‘ AS ‘2011-07‘, ‘--‘ AS ‘2011-08‘, ‘--‘ AS ‘2011-09‘, ‘--‘ AS ‘2011-10‘, ‘--‘ AS ‘2011-11‘, ‘--‘ AS ‘2011-12‘, ‘--‘ AS ‘以后年度合计‘ from Project where ProjectGUID=@ProjectGUID
还有产品:
select Project.ProjectName+‘.‘+a.ProductCode as orderCode,a.ProductGUID,a.ProductName, ‘--‘ AS ‘项目合计‘, ‘--‘ AS ‘以前年度合计‘, ‘--‘ AS ‘2011年合计‘, ‘--‘ AS ‘2011-01‘, ‘--‘ AS ‘2011-02‘, ‘--‘ AS ‘2011-03‘, ‘--‘ AS ‘2011-04‘, ‘--‘ AS ‘2011-05‘, ‘--‘ AS ‘2011-06‘, ‘--‘ AS ‘2011-07‘, ‘--‘ AS ‘2011-08‘, ‘--‘ AS ‘2011-09‘, ‘--‘ AS ‘2011-10‘, ‘--‘ AS ‘2011-11‘, ‘--‘ AS ‘2011-12‘, ‘--‘ AS ‘以后年度合计‘ from #product a left join Project on a.ProjectGUID=Project.ProjectGUID
部分数据如图:
最后从表#tempSaleDtl3 联接产品表#product 与项目表查询出最后的显示:
--从产品表和Project表、#tempSaleDtl3中加入类型行数据 select c.ProjectName+‘.‘+b.ProductCode+‘.‘+a.typecode as orderCode,a.ProductGUID, a.[type], cast(a.[项目合计] as varchar(20)), cast(a.[以前年度合计] as varchar(20)), cast(a.[2011年合计] as varchar(20)), cast(a.[2011-01] as varchar(20)), cast(a.[2011-02] as varchar(20)), cast(a.[2011-03] as varchar(20)), cast(a.[2011-04] as varchar(20)), cast(a.[2011-05] as varchar(20)), cast(a.[2011-06] as varchar(20)), cast(a.[2011-07] as varchar(20)), cast(a.[2011-08] as varchar(20)), cast(a.[2011-09] as varchar(20)), cast(a.[2011-10] as varchar(20)), cast(a.[2011-11] as varchar(20)), cast(a.[2011-12] as varchar(20)), cast(a.[以后年度合计] as varchar(20)) from #tempSaleDtl3 a left join #product b on a.ProductGUID=b.ProductGUID left join Project c on b.ProjectGUID=c.ProjectGUID
以上三块数据加在一起,用union ALL,然后排个序就得到最开始效果图中的结果,再次来看看:
其中注意orderCode,这里用到层级,前台显示时可以更方便显示层级关系。
最后完整的code:
--从Project表中加入项目数据 select * from ( select ProjectName as orderCode,ProjectGUID,ProjectName, ‘--‘ AS ‘项目合计‘, ‘--‘ AS ‘以前年度合计‘, ‘--‘ AS ‘2011年合计‘, ‘--‘ AS ‘2011-01‘, ‘--‘ AS ‘2011-02‘, ‘--‘ AS ‘2011-03‘, ‘--‘ AS ‘2011-04‘, ‘--‘ AS ‘2011-05‘, ‘--‘ AS ‘2011-06‘, ‘--‘ AS ‘2011-07‘, ‘--‘ AS ‘2011-08‘, ‘--‘ AS ‘2011-09‘, ‘--‘ AS ‘2011-10‘, ‘--‘ AS ‘2011-11‘, ‘--‘ AS ‘2011-12‘, ‘--‘ AS ‘以后年度合计‘ from Project where ProjectGUID=@ProjectGUID ----项目1 8FA659C8-3DA9-4330-B277-9B517E67606D 项目1 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- union all --从产品表和Project表中加入合计行数据 select Project.ProjectName+‘.‘+a.ProductCode as orderCode,a.ProductGUID,a.ProductName, ‘--‘ AS ‘项目合计‘, ‘--‘ AS ‘以前年度合计‘, ‘--‘ AS ‘2011年合计‘, ‘--‘ AS ‘2011-01‘, ‘--‘ AS ‘2011-02‘, ‘--‘ AS ‘2011-03‘, ‘--‘ AS ‘2011-04‘, ‘--‘ AS ‘2011-05‘, ‘--‘ AS ‘2011-06‘, ‘--‘ AS ‘2011-07‘, ‘--‘ AS ‘2011-08‘, ‘--‘ AS ‘2011-09‘, ‘--‘ AS ‘2011-10‘, ‘--‘ AS ‘2011-11‘, ‘--‘ AS ‘2011-12‘, ‘--‘ AS ‘以后年度合计‘ from #product a left join Project on a.ProjectGUID=Project.ProjectGUID ----项目1 8FA659C8-3DA9-4330-B277-9B517E67606D 项目1 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ----项目1.00 00000000-0000-0000-0000-000000000000 合计 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ----项目1.产品1 18908255-DB67-4EA3-A231-8BB39D5B748B 产品1 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ----项目1.产品2 EDB216A9-EBB8-4F2C-AE4E-0A989EC7A993 产品2 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ----项目1.产品3 7040241F-5A66-4F17-AACA-7CBE2FB3BCB9 产品3 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ----项目1.产品4 108778CD-47C0-4258-9CB6-1FBE90CDEBDA 产品4 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ----项目1.产品5 43F7B9BA-EF91-4A38-A048-090179F33C9B 产品5 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- union ALL --从产品表和Project表、#tempSaleDtl3中加入类型行数据 select c.ProjectName+‘.‘+b.ProductCode+‘.‘+a.typecode as orderCode,a.ProductGUID, a.[type], cast(a.[项目合计] as varchar(20)), cast(a.[以前年度合计] as varchar(20)), cast(a.[2011年合计] as varchar(20)), cast(a.[2011-01] as varchar(20)), cast(a.[2011-02] as varchar(20)), cast(a.[2011-03] as varchar(20)), cast(a.[2011-04] as varchar(20)), cast(a.[2011-05] as varchar(20)), cast(a.[2011-06] as varchar(20)), cast(a.[2011-07] as varchar(20)), cast(a.[2011-08] as varchar(20)), cast(a.[2011-09] as varchar(20)), cast(a.[2011-10] as varchar(20)), cast(a.[2011-11] as varchar(20)), cast(a.[2011-12] as varchar(20)), cast(a.[以后年度合计] as varchar(20)) from #tempSaleDtl3 a left join #product b on a.ProductGUID=b.ProductGUID left join Project c on b.ProjectGUID=c.ProjectGUID ) t1 order by orderCode
最重要的重要的!!最后不要忘了删除临时表:
drop table #product drop table #TempAllSaleDtl DROP TABLE #TempSaleDtl DROP TABLE #tempSaleDtl2 DROP TABLE #tempSaleDtl3 DROP TABLE #ProductSaleArea
至此 数据报表系列已结束,以上也只是提供一下思路,再次提醒一下各位在作以上每一步数据处理时请用数据集合的思维来思考,可能对于一般人来说长篇幅的存储过程编写没有写过,文中涉及到的技巧和思路是值得借鉴的,其中不理解的可以回过头来将之前系列的各部分基础知识点复习一下,然后一步步将结果打印出来测试,在脑袋里留下个前一步的数据,然后再思考下一步的数据怎么处理。如果你能毫无鸭梨的完全写出来,那恭喜你,你已经进阶为小大师,将会迎娶白富美,走上人生巅峰……想想是不是有点小激动……
最终的SQL,其中两个参数 需要查询的项目ID @ProjectGUID和需要查询的年份 @Year 可以由外部传入,可以自己写个存储过程,在这里就不演示了:
DBCC DROPCLEANBUFFERS DBCC FREEPROCCACHE --SET STATISTICS IO ON --SET STATISTICS TIME ON DECLARE @ProjectGUID UNIQUEIDENTIFIER SET @ProjectGUID=‘8FA659C8-3DA9-4330-B277-9B517E67606D‘ DECLARE @Year CHAR(4) SET @Year=‘2011‘ /*临时表说明 #product:用项目过滤后,将“合计”作为一个产品的集合 #TempAllSaleDtl:通过项目过滤后的销售明细,所有月的 #ProductSaleArea:各个产品的总面积,用于计算比例 #TempSaleDtl:通过日期过滤,且加工过后的销售明细,包括增加累积列,以前年度、以后年度、项目合计的记录 #tempSaleDtl2:列转行后的数据集 #tempSaleDtl3:行转列后的数据集 */ select ProductGUID,ProductName,ProjectGUID,ProductCode into #product from( select ProductGUID,ProductName,ProjectGUID,ProductName as ProductCode from Product where ProjectGUID=@ProjectGUID union all select ‘00000000-0000-0000-0000-000000000000‘,‘合计‘,@ProjectGUID,‘00‘ as ProductCode ) a --SELECT * FROM #product ----查找项目所有产品的销售明细:#TempAllSaleDtl SELECT ProductGUID,YearMonth,SaleAmount,SaleArea,SaleNum,SalePrice INTO #TempAllSaleDtl FROM dbo.SaleDtl WHERE ProductGUID IN ( SELECT ProductGUID FROM dbo.Product WHERE ProjectGUID=@ProjectGUID ) --SELECT * FROM #TempAllSaleDtl --ORDER BY ProductGUID,YearMonth --根据现有数据统计,向#TempAllSaleDtl添加总合计记录 insert into #TempAllSaleDtl(ProductGUID,YearMonth,SaleAmount,SaleArea,SaleNum,SalePrice) select ‘00000000-0000-0000-0000-000000000000‘,YearMonth,SUM(SaleAmount),SUM(SaleArea),SUM(SaleNum),SUM(SaleAmount)/SUM(SaleArea) from #TempAllSaleDtl group by YearMonth --SELECT * FROM #TempAllSaleDtl --ORDER BY ProductGUID,YearMonth --查找某年的销售明细:#TempSaleDtl SELECT ProductGUID,YearMonth,SaleAmount,SaleArea,SaleNum,SalePrice, SalePrice AS ljSaleArea, SalePrice AS blSaleArea, SalePrice AS ljSaleAmount INTO #TempSaleDtl FROM #TempAllSaleDtl WHERE LEFT([YearMonth],4)=@Year --SELECT * FROM #TempSaleDtl --ORDER BY ProductGUID,YearMonth --获取项目各个产品的总销售面积:#ProductSaleArea SELECT ProductGUID,SUM(SaleArea) AS all_SaleArea INTO #ProductSaleArea FROM #TempAllSaleDtl GROUP BY ProductGUID --SELECT * FROM #ProductSaleArea --ORDER BY ProductGUID --添加2011合计列的记录(本年度的各产品的所有面积、金额、均价总合计) insert into #TempSaleDtl( ProductGUID,YearMonth,SaleAmount,SaleArea,SaleNum,SalePrice,ljSaleArea, blSaleArea,ljSaleAmount) select ProductGUID,@Year+‘-13‘,SUM(SaleAmount),SUM(SaleArea),SUM(SaleNum),SUM(SaleAmount)/SUM(SaleArea),0,0 热心网友 时间:2022-04-08 19:25 有重复的,只介绍部分有用并且关键的。由于你的代码是部分的,所以只能大概的给你解释,让你知道每一步基本上的作用,不能详细的解释哪个变量是干什么的,那需要看到整个程序后才可以的。希望你能理解。有问题可以再直接向我提问。祝你好运、。
USE [XYS]---确定数据库名
GO
/****** Object: StoredProcere [dbo].[usp_kpi_rfid_report2] Script Date: 03/22/2011 14:11:12 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[usp_kpi_rfid_report2] --存储结构作用的表名
@factory varchar(10),----定义变量
@ship_date_from varchar(10),
@ship_date_to varchar(10),
@work_date varchar(10),
@fz_major varchar(3),
@zj_major varchar(3),
@component varchar(3),
@component2 varchar(3),
@WC varchar(1),
@PX varchar(1),
@PO varchar(20)
AS
/*
exec usp_kpi_rfid_report2 ---将读取到的数据重新命名
@factory='', --工厂
@ship_date_from = '', --船期开始
@ship_date_to = '', --船期结束
@work_date= '22-03-2011', --生产日期
@fz_major = '001', --发毛工序
@zj_major = '003', --配扎工序
@component = '001', --全件部件
@component2 = '996', --后整部件
@WC = '1', --查询未完成,=1可以查询已完成
@PX = '0', --=0按PO排序,=1按交货期排序
@po='hb0084'
*/
declare @work_date_from datetime, --创建触发器
@work_date_to datetime,定义变量
@date datetime,
@px_txt varchar(20),
@px_sql varchar(1000)
---查询数据,按照上面的变量查询
使用触发器判断数据是否改变如果改变就进行相用的处理。
if len(@ship_date_from) = 0 or @ship_date_from = '-1' or @ship_date_from is null
select @ship_date_from = '', @work_date_from = nullelse
select @work_date_from = convert(datetime, @ship_date_from, 105)
if len(@ship_date_to) = 0 or @ship_date_to = '-1' or @ship_date_to is null
select @ship_date_to = '', @work_date_to = null
else
select @work_date_to = convert(datetime, @ship_date_to, 105)
if len(@work_date) = 0 or @work_date = '-1' or @work_date is null
select @work_date = '', @date = null
else
select @date = convert(datetime, @work_date, 105)
if @px='0'
select @px_txt='sp_ord_no'
else
select @px_txt='po_startdate'热心网友 时间:2022-04-08 20:43
ALTER PROCEDURE [dbo].[usp_kpi_rfid_report2] //创建存储过程
@factory varchar(10),//定义参数
declare @work_date_from datetime,//定义时间类型的参数
@work_date_to datetime,
@date datetime,
@px_txt varchar(20),//定义字符串类型的参数
@px_sql varchar(1000)
if len(@ship_date_from) = 0 or @ship_date_from = '-1' or @ship_date_from is null//if的条件表达式(如果@ship_data_from等于0或-1或空)
select @ship_date_from = '', @work_date_from = null//满足if中的表达式(为@ship_data_from“赋值”等于空值)
else
select @work_date_from = convert(datetime, @ship_date_from, 105) //“convert”类型的转化