金蝶K3直接SQL报表实现动态行转列报表

我们知道,在BOS开发中,想实现动态行转列报表,可以使用交叉分析表来实现,但交叉分析表不太灵活,比如当动态列中有需要复杂的逻辑运算来实现时就无能为力了,下面介绍使用直接SQL报表来实现,也许能给你一点启发。

以如下表数据为例,来说明如何实现:

要求实现这样的报表样式:

具体实现步骤如下:

1、使用以下存储过程随便建一个直接SQL报表「测试行列转换报表」。

CREATE   Procedure   sp_Rpt_Test
AS
SET NOCOUNT ON

SELECT FUserName 姓名,FSubject 学科,FScore 分数 FROM t_Test

SET NOCOUNT OFF

GO

2、使用如下SQL语句在数据库中找到此SQL报表的ID。

select FReportID,* from ICClassSQLReport where FName_CHS ='测试行列转换报表'

3、修改创建此SQL报表的存储过程,注意将下面语句中的「3AB197CF-443E-4555-B0F7-BD3971C50819」这个UUID替换为第二步中你自己的SQL报表的「FReportID」:

ALTER   Procedure   sp_Rpt_Test
AS
SET NOCOUNT ON

DECLARE @vSQL VARCHAR(MAX)
DECLARE @vColumn VARCHAR(MAX)
DECLARE @vSumColumn VARCHAR(MAX)

SET @vSQL=''
SET @vColumn=''
SET @vSumColumn=''

SELECT @vColumn=@vColumn+','+FSubject+'',@vSumColumn=@vSumColumn+'+ISNULL(['+FSubject+'],0)'
FROM t_Test GROUP BY FSubject ORDER BY FSubject

SET @vSQL='SELECT *,'+STUFF(@vSumColumn,1,1,'')+' [总分数] INTO t_Rpt_Test FROM(
    SELECT FUserName 姓名,FSubject,FScore FROM t_Test ) t
    PIVOT(SUM(FScore) FOR FSubject IN('+STUFF(@vColumn,1,1,'')+')) tt'

EXEC(@vSQL)

DECLARE @FSequence INT
DECLARE @FValue VARCHAR(50)
SET @vSQL=''
DELETE FROM ICClassSQLReportDesc WHERE FReportID='3AB197CF-443E-4555-B0F7-BD3971C50819'
DECLARE t_Cur CURSOR FOR select FSequence,FValue from dbo.fn_SplitStringToTable('姓名'+ @vColumn +',总分数',',')
OPEN t_Cur
FETCH NEXT FROM t_Cur INTO @FSequence,@FValue   
WHILE(@@FETCH_STATUS=0)
BEGIN
    IF @FSequence=1
    SET @vSQL=@vSQL+'insert into ICClassSQLReportDesc ( FCanInput,FColCaption_CHS,FColCaption_CHT,FColCaption_EN,FColName,FColType,FCondition,FContrlExt,FDSPFieldName,FFNDFieldName,FFormat,FLookUpClassID,FLookUpType,FMustInput,FNeedFilter,FReportID,FSRCFieldName,FSRCTableName,FSRCTableNameAs,FTableID,FVisible ) values (''1'',  '''+@FValue+''',  '''+@FValue+''',  '''+@FValue+''',  '''+@FValue+''',  1,  '''',  0,  '''',  '''',  '''',  0,  0,  ''0'',  ''1'',  ''{3AB197CF-443E-4555-B0F7-BD3971C50819}'',  '''',  '''',  '''',  -1,  1)'
    ELSE
    SET @vSQL=@vSQL+'insert into ICClassSQLReportDesc ( FCanInput,FColCaption_CHS,FColCaption_CHT,FColCaption_EN,FColName,FColType,FCondition,FContrlExt,FDSPFieldName,FFNDFieldName,FFormat,FLookUpClassID,FLookUpType,FMustInput,FNeedFilter,FReportID,FSRCFieldName,FSRCTableName,FSRCTableNameAs,FTableID,FVisible ) values (''1'',  '''+@FValue+''',  '''+@FValue+''',  '''+@FValue+''',  '''+@FValue+''',  3,  '''',  0,  '''',  '''',  '''',  0,  0,  ''0'',  ''1'',  ''{3AB197CF-443E-4555-B0F7-BD3971C50819}'',  '''',  '''',  '''',  -1,  1)'
    
    FETCH NEXT FROM t_Cur INTO @FSequence,@FValue   
END
CLOSE t_Cur
DEALLOCATE t_Cur

EXEC(@vSQL)

SELECT * FROM t_Rpt_Test

DROP TABLE t_Rpt_Test

SET NOCOUNT OFF

GO

完毕,运用一下看看效果,是不是完美实现?举一反三,亲自动手做一个试试。

注:
————————————————
版权声明:本文为CSDN博主「Eypsn」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Eypsn/article/details/109063268