`

多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  
     

相关推荐

    SQL COOKBOOK(压缩1/2)

    然而从中可以找到许多共同的问题及其解决方案,这些解决方案中用到许多技巧,读者学到这些技巧就可以将它们扩展并应用到《SQL Cookbook中文版》不可能覆盖的其他新问题上。 毫无疑问,《SQL Cookbook中文版》的目标...

    SQL SERVER 2000开发与管理应用实例

    中文版SQL Server 2000开发与管理应用实例-目录: 第 1 章 安装和配置SQL Server 1 1.1 SQL Server的版本和版本选择 1 1.2 安装SQL Server的常见问题 3 1.3 如何理解实例 5 1.4 如何实现无值守安装 5 ...

    SQL COOKBOOK(压缩2/2)

    然而从中可以找到许多共同的问题及其解决方案,这些解决方案中用到许多技巧,读者学到这些技巧就可以将它们扩展并应用到《SQL Cookbook中文版》不可能覆盖的其他新问题上。 毫无疑问,《SQL Cookbook中文版》的目标...

    SQL Server 2008管理员必备指南(超高清PDF)Part3

    SQL Server专家的呕心力作,数据库管理员的实战宝典,全面、深入地剖析SQL Server2008新特性,结构独特,实例丰富,操作性强。 作者简介 作者:(美国)斯坦里克 (William R.Stanek) 译者:贾洪峰 William R.Stanek...

    Oracle SQL高级编程(资深Oracle专家力作,OakTable团队推荐)--随书源代码

    作者通过总结各自多年的软件开发和教学培训经验,与大家分享了掌握Oracle SQL所独有的丰富功能的技巧所在,内容涵盖SQL执行、联结、集合、分析函数、子句、事务处理等多个方面。读者可以学习到以下几个方面的技巧:...

    SQL Server 2008管理员必备指南(超高清PDF)Part1

    SQL Server专家的呕心力作,数据库管理员的实战宝典,全面、深入地剖析SQL Server2008新特性,结构独特,实例丰富,操作性强。 作者简介 作者:(美国)斯坦里克 (William R.Stanek) 译者:贾洪峰 William R.Stanek...

    SQL.Server.2008管理员必备指南.part4.rar(4/4)

     2.1.4 使用SQL Server 2008管理报表 26  2.2 规划SQL Server 2008的部署 27  2.2.1 建立服务器的性能系统 27  2.2.2 配置I/O子系统 28  2.2.3 确保可用性和可伸缩性 30  2.2.4 确保连接性和数据访问 31  ...

    SQL Server 2008管理员必备指南(超高清PDF)Part2

    SQL Server专家的呕心力作,数据库管理员的实战宝典,全面、深入地剖析SQL Server2008新特性,结构独特,实例丰富,操作性强。 作者简介 作者:(美国)斯坦里克 (William R.Stanek) 译者:贾洪峰 William R.Stanek...

    SQL Server 2008高级程序设计 4/6

     本书首先介绍SQL Server 2008的新功能,然后在更详实的示例代码的引导下全面深入地展开论述,讨论了如何编写复杂查询、构建各种数据结构以及提高应用程序性能,还讲述了如何管理高级脚本和数据库以及如何确定和...

    sqlserver2000基础(高手也有用)

    6.3.2 多列转置 184 6.3.3 动态列 185 6.3.4 动态列中的字符溢出处理 188 6.3.5 特殊的交叉报表 191 6.4 典型数据统计案例 193 6.4.1 库存明细账查询 193 6.4.2 同期及上期数据对比 197 6.4.3 动态...

    报表性能优化方案之巧用相邻连续分组

    相邻连续分组的操作,是...尤其是,在配合SQL中已排好序的列,对其实现的分组时,使用此分组方式其性能比普通分组快些。如下简单示例,查看其报表执行数据信息,可看出其分组方式比普通分组方式更能提高其报表的性能。

    SQL Server 2008高级程序设计 2/6

     本书首先介绍SQL Server 2008的新功能,然后在更详实的示例代码的引导下全面深入地展开论述,讨论了如何编写复杂查询、构建各种数据结构以及提高应用程序性能,还讲述了如何管理高级脚本和数据库以及如何确定和...

    SQL.Server.2008管理员必备指南.part2.rar(2/4)

     2.1.4 使用SQL Server 2008管理报表 26  2.2 规划SQL Server 2008的部署 27  2.2.1 建立服务器的性能系统 27  2.2.2 配置I/O子系统 28  2.2.3 确保可用性和可伸缩性 30  2.2.4 确保连接性和数据访问 31  ...

    SQL.Server.2008管理员必备指南.part1.rar(1/4)

     2.1.4 使用SQL Server 2008管理报表 26  2.2 规划SQL Server 2008的部署 27  2.2.1 建立服务器的性能系统 27  2.2.2 配置I/O子系统 28  2.2.3 确保可用性和可伸缩性 30  2.2.4 确保连接性和数据访问 31  ...

    SQL.Server.2008管理员必备指南.part3.rar(3/4)

     2.1.4 使用SQL Server 2008管理报表 26  2.2 规划SQL Server 2008的部署 27  2.2.1 建立服务器的性能系统 27  2.2.2 配置I/O子系统 28  2.2.3 确保可用性和可伸缩性 30  2.2.4 确保连接性和数据访问 31  ...

Global site tag (gtag.js) - Google Analytics