`

多sql结果集按列合并新结果报表实现方案

 
阅读更多
场景:某个报表一个sql出不来,需要多个sql的结果集合并加工
方案要点:按列抽取sql数据,再矩阵转置方式合成目标报表。
方案难点:
  1,各sql结果行数不一致时,空列要按空集处理补数据加工。
  2,实现跨表字断的表达式计算。

部分代码:
 # 关联报表子报表
  def association
    @child_columns = []
    @child_reports = []
    @execute_child_reports = []
    @child_temporary_reports = @temporary_report.child_reports
    @child_temporary_reports.each do |child|
      @child_columns << child.columns.split(" ")
      child_reports = ExecuteReport.new(child.get_report_sql(params)).report 
      @execute_child_reports << child_reports
      @child_reports << Kaminari.paginate_array(child_reports, total_count: child_reports.size).page(params[:page]).per(20)
    end
  end

  # 合并报表子报表
  def composite
    # (默认内容最多的sql放在父亲sql,关键列放在左边)
    # 当多sql数据行不一致时,按照合并关键列补充空数据
    unless (@execute_child_reports.inject([]){|o,j| o<<j.size } << @execute_reports.size).uniq.size == 1
      # 查询合并关键列列数
      @composite_columns = @columns & @child_columns.first
      @new_execute_child_reports = ("[] " * @child_columns.size).split(" ").map{|_|eval(_)}
      @execute_reports.each_with_index do |parent_report,i|
        base_columns = parent_report[0..@composite_columns.size-1]
        @execute_child_reports.each_with_index do |child_report,j|
          compare_columns = child_report.map{|child| child[0..@composite_columns.size-1] }
          if compare_columns.include? base_columns
            child_report_index = compare_columns.index(base_columns)
            @new_execute_child_reports[j][i] = child_report.to_a[child_report_index]
          else
            create_child_columns = ("- " * @child_columns[j].size).split(" ") 
            create_child_columns[0..@composite_columns.size-1] = base_columns
            @new_execute_child_reports[j][i] = create_child_columns
          end
        end
      end
      # 重新赋值
      @execute_child_reports =  @new_execute_child_reports
    end

    @moder_columns = []
    @moder = []
    @sentence_expression = []
    arr = ('a'..'z').to_a
    composite_sentence = @temporary_report.composite_sentence.split("|")[0].split(",")
    composite_sentence_expression_str = @temporary_report.composite_sentence.split("|")[1].to_s
    composite_sentence_expression = composite_sentence_expression_str.split(",")
    composite_sentence.each do |_|
      mod = arr.index(_[0])
      moder = (mod == 0 ? @execute_reports : @execute_child_reports[mod-1])
      mod_columns_size = _[1].to_i
      moder_value = moder.map{|_|_[mod_columns_size]}

      # 表达式运算
      if composite_sentence_expression_str.present? && composite_sentence_expression_str.include?(_)
        moder_value_set = moder.map{|_|_[mod_columns_size].to_f}
        instance_variable_set("@#{_}_arr",moder_value_set)
        @sentence_expression << "@#{_}"
      end

      @moder << moder_value
      moder_column = (mod == 0 ? @columns[mod_columns_size] : @child_columns[mod-1][mod_columns_size])
      @moder_columns << moder_column
    end

    # 表达式运算
    composite_sentence_expression.each do |_|
      moder_column = _.split(":").first
      @expression = _.split(":").last
      moder_values = []
      @moder.first.size.times do |i|
        @sentence_expression.each do |ex|
          moder_value_set = instance_variable_get("#{ex}_arr")[i]
          instance_variable_set("#{ex}",moder_value_set)
        end
        moder_values << eval(@expression).to_f.round(2)
      end
      @moder << moder_values
      @moder_columns << moder_column
    end if composite_sentence_expression_str.present?

    # 矩阵行列倒置
    @reports = Matrix.columns(@moder).to_a
    @columns = @moder_columns
    # 合并报表子报表的下载xls
    if params[:xls]
      search_conditions = @temporary_report.search_conditions(params)
      send_data ExecuteReport.to_xlsx(@report_name,@columns,@reports,search_conditions), type: 'text/xls', filename: "#{Time.now}#{@report_name}.xls"
    else
      @reports = Kaminari.paginate_array(@reports, total_count: @reports.size).page(params[:page]).per(20) 
    end
  end


源码关注:
https://github.com/jamst/pre-report
0
0
分享到:
评论
1 楼 masuweng 2018-03-28  
     

相关推荐

    用子表的方式解决ireport相同列合并问题

    本文将详细介绍一种解决方案,即利用子报表的方式来解决ireport中的相同列合并问题。 首先,我们需要创建一个主报表(mianDt.jrxml)。主报表是报表的基本框架,用于定义报表的总体结构和样式。在主报表中,添加...

    系统直接SQL语句报表双表头解决方案.pdf

    4. 执行SQL语句并查看报表生成的结果。 ### 知识点三:双表头报表的解决方案 双表头报表是指报表中存在两行表头信息的报表格式。在金蝶K/3系统中,通过SQL语句直接生成双表头报表需要执行一系列的操作来合并表头。...

    C#(vs2005)水晶报表+SQL联合查询

    SQL联合查询用于合并两个或多个SELECT语句的结果集,形成一个单一的结果。在水晶报表中,联合查询可以用来从多个表或视图中提取数据,创建复杂的数据分析报告。联合查询主要有以下几种类型: 1. **UNION**:合并结果...

    sql server 2008 将一列值转换成一个字符串

    在SQL Server 2008中,有时我们需要将表中的某一列数据合并成一个单独的字符串,例如将员工编号列合并成一个逗号分隔的字符串。这种操作在生成报表、邮件合并等功能中非常有用。本文的目标是通过一个具体的例子来...

    sql合并相同行

    ### SQL合并相同行知识点详解 #### 一、背景与需求分析 在数据库处理过程中,我们经常会遇到需要将具有相同特征的记录进行汇总的情况。比如,本案例中的需求就是需要将同一客户的购买产品ID进行合并,形成一条记录...

    水电管理系统(含有水晶报表,打印,SQL的报表合并,计算,数据备份,恢复。月结处理)

    水电管理系统是一款专为物业管理或公共设施管理设计的软件系统,其核心功能涵盖了水电用量的记录、计费、报表生成、打印、数据备份与恢复以及月结处理等多个方面。这款系统在实际应用中表现出稳定性和可靠性,是作者...

    两台SQL-Server数据同步解决方案

    ### 两台SQL Server数据同步解决方案详解 #### 一、概述 在当今信息化时代,数据同步成为企业级应用中不可或缺的一部分。特别是在分布式环境中,确保不同地理位置的数据库保持一致性和实时性变得尤为重要。本文将...

    vs2005中水晶报表实现

    - 在Push模式下,可以根据用户输入动态构造SQL查询,然后将结果数据集设置到报表中。 6. **安全性考虑**: 页面输入拼接SQL可能存在SQL注入风险,因此需要确保对用户输入进行适当的验证和清理。 7. **报表性能**...

    通过SQL语句实现行列转换的几种方法

    除此之外,还会涉及将多列或多行的数据合并为字符串,或将字符串拆分为多列或多行等操作。本文将重点探讨如何通过SQL语句实现这些转换,特别是将多行数据转换为单一字符串的情况。 #### 一、概述 行列转换可以分为...

    Proc SQL by Example, Using SQL within SAS

    深入探讨了UNION操作符的功能和使用技巧,包括如何使用UNION来合并多个查询结果集。 #### 6.7 INTERSECT 介绍INTERSECT操作符的用法,即如何找到两个或多个查询结果集的交集。 #### 6.8 EXCEPT 探讨EXCEPT操作符...

    C# 常用整合的资料,NET环境下水晶报表使用总结,水晶报表是一个优秀的报表开发工具,本人在开发通用管理系统的时候,所有报表都使用水晶报表,其简单、易用和强大的功能令笔者倍加喜爱,现将水晶报表使用手记呈现给大家

    4. **填充报表数据**:在C#代码中,使用`CrystalDecisions.CrystalReports.Engine.ReportDocument`类加载报表文件,然后使用`SetDataSource`方法绑定数据集,实现报表的数据填充。 5. **嵌入报表到应用程序**:将...

    Microsoft SQL Server 2005 向后兼容组件SQLServer2005_BC.msi

    安装此组件后,用户可以继续使用那些设计时依赖SQL Server 2005特性的应用程序,而无需担心与新版本的不兼容问题。 在SQL Server 2005中,有以下几个核心知识点: 1. **Transact-SQL (T-SQL)**:这是SQL Server的...

    12种优秀开源报表工具整理

    在报表的设计过程中,用户可以随时预览报表的结果。Pentaho商业智能项目提供企业级报表制作、分析、数据挖掘与工作流的功能。 3. OpenReports OpenReports提供基于Web的灵活报表解决方案,支持PDF、HTML和XLS报表...

    sql server 课程设计案例

    此外,还有更复杂的JOIN操作用于合并多个表的数据,以及GROUP BY和HAVING子句用于数据分组和过滤。 3. 触发器和存储过程: 存储过程是预编译的SQL语句集合,可提高性能并简化复杂的操作。触发器则是在特定数据库...

    SQL2000中文企业版

    再者,SQL2000的复制功能也是其亮点之一,它支持快照复制、事务复制和合并复制等多种模式,使得数据能够在多个地点之间进行同步,满足远程分支机构或分布式系统的需求。这对于企业级应用来说,是实现数据备份、灾难...

    用友报表模块式手册

    - **合并查询报表**:结合多个查询结果,生成半录入半嵌入式报表。 ##### 5. 算法类报表 - **普通占比报表**:计算非投影类数据的占比。 - **投影占比报表**:针对投影类数据进行占比计算。 - **程序送数报表**:...

    ORACLE__SQL.pdf SQL.Cookbook.pdf

    3. **数据转换**:如何通过SQL进行数据整理,如计算新列、拆分和合并字段。 4. **报表和分析**:如何构建复杂的报表,使用GROUP BY、HAVING和透视表进行数据分析。 5. **数据导入导出**:介绍如何将数据导入到...

    SQL2000帮助文档

    12. **报表服务**:提供自定义报告的生成和分发,是BI解决方案的关键部分。 13. **DTS(数据转型服务)**:用于数据导入、导出和转换,是数据集成的重要工具。 14. **XML支持**:SQL Server 2000开始引入对XML的...

    导出Excel多个单元格合并及图片插入

    ### 导出Excel多个单元格合并及图片插入 #### 问题描述 在安全生产项目中,为了更好地管理和展示巡检记录,通常需要将这些记录导出为Excel文件,并且每个巡检项都应附带相应的抓图。这不仅要求能够有效地处理数据...

    NC65企业报表浮动行取数手册.doc

    合并方案表iufo_hbscheme记录了报表的合并方案名称和数据版本号,这在处理多维度、跨数据源的数据合并时非常关键。 生成带有浮动行的企业报表时,SQL脚本的编写步骤如下: 1. 确定指标数据表IUFO_MEASURE_DATA_X,...

Global site tag (gtag.js) - Google Analytics