上篇介绍了 交叉表的简单实现1:使用存储过程,这里采取在前端程序实现。
实现要点:
1。读取所有目标成绩(flatScroreTable)
2。从目标成绩中提取考试时间(不重复),作为交叉表的列表头
3。从目标成绩中提取考试科目(不重复),作为交叉表的行表头
4。根据2动态构建一个DataTable(crossScroreTable),此DataTable具有一个科目列,若干考试时间列,以及其他信息。
5。将3中的考试科目写入DataTable
6。从flatScroreTable中读取成绩值填入crossScroreTable对应单元格
说明:便于理解,这里将交叉表crossScroreTable想象成一张Excel表,列名就当作列表头,科目名就当作行表头。

主要代码:

void LoadScoreData()
    {
        读取指定学生的所有成绩#region 读取指定学生的所有成绩
        string stuName = drpStu.SelectedValue;        
        string connStr = "SERVER=.;DATABASE=DemoLib;UID=sa";
        string sql = "SELECT SubjectName, StudentName, ScoreValue, ExamDate  FROM t_Score WHERE StudentName = @StuName";        
        DataSet ds = new DataSet();        
        SqlDataAdapter da = new SqlDataAdapter(sql, connStr);
        da.SelectCommand.CommandType = CommandType.Text;
        da.SelectCommand.Parameters.Add("@StuName", stuName);           
        da.Fill(ds, "FlatScore");
        #endregion 读取指定学生的所有成绩

        DataTable flatScoreTable = ds.Tables[0];
        DataView flatScoreView = new DataView(flatScoreTable);
        // 读取科目列表,排除重复
        DataTable subjectList;
        // .NET 2 using the ToTable method supported by DataView
        //subjectList = flatScoreView.ToTable("SubjectList", true, "SubjectName");        
        subjectList = SelectDistinct(flatScoreTable, "SubjectList", true, "SubjectName");        
        // 读取考试时间列表,排除重复
        // .NET 2
        DataTable examDateList;
        // .NET 2 using the ToTable method supported by DataView
        //examDateList = flatScoreView.ToTable("ExamDateList", true, "ExamDate");        
        examDateList = SelectDistinct(flatScoreTable, "ExamDateList", true, "ExamDate");        
       
        创建 交叉表#region 创建 交叉表
        DataTable crossScoreTable = new DataTable();
        
        构造表模式#region 构造表模式
        // 科目 列
        crossScoreTable.Columns.Add("科目", typeof(string));
        // 考试时间 列,以时间为列名
        foreach (DataRow r in examDateList.Rows) {
            crossScoreTable.Columns.Add(((DateTime)r[0]).ToString("yyyy年M月dd日"), typeof(string));
        }
        #endregion 构造表模式
        
        从成绩表读取并写入数据#region 从成绩表读取并写入数据        
        DataColumnCollection cols = crossScoreTable.Columns;
        // 按先科目(行)后时间(列)遍历        
        foreach (DataRow r in subjectList.Rows){
            DataRow newRow = crossScoreTable.NewRow();
            // 科目
            newRow[0] = r[0];
            // 成绩,遍历时间
           for(int i=1; i< cols.Count; i++) {
               // 返回具有指定科目和指定考试的成绩
               // eg. "SubjectName='孙光' AND ExamDate='2007-5-19'"
               flatScoreView.RowFilter = String.Format("SubjectName='{0}' AND ExamDate='{1}'", r[0], examDateList.Rows[i-1][0]);
               if (flatScoreView.Count > 0) {
                   newRow[cols[i]] = flatScoreView[0]["ScoreValue"];
               }
            }
            // 加入新表
            crossScoreTable.Rows.Add(newRow);
        }        
        #endregion 从成绩表读取并插入数据

        #endregion 创建 交叉表

        // 绑定,输出数据
        grdCrossScore.DataSource = crossScoreTable;
        grdCrossScore.DataBind();
        grdFlatScore.DataSource = flatScoreTable;
        grdFlatScore.DataBind();
        grdSubjectList.DataSource = subjectList;
        grdSubjectList.DataBind();
        grdExamDate.DataSource = examDateList;
        grdExamDate.DataBind();
    }

看下这个方法:

DataTable SelectDistinct(DataTable sourceTable, string newTableName, bool distinct, params string[] columnNames)

扩展 ADO.NET 1.x 中DataTable 以及 DataView 均无法支持的:SELECT DISTINCT Column1,Column2.... 语法,(选择不重复的行)
如果 ADO.NET 2.0 中我们就可以直接使用 DataView 的 ToTable 方法的重载版本:

public DataTable ToTable(bool distinct, params string[] columnNames);

public DataTable ToTable(string tableName, bool distinct, params string[] columnNames);

SelectDistinct 网上有很多版本,原理基本一样,只是效率问题,这里是修改于 Erik Porter 的Select DISTINCT on DataTable。

SelectDistinct完整代码:


implements such as 'SELECT DISTINCT Column0, Column1' sql clause for DataTable.#region implements such as 'SELECT DISTINCT Column0, Column1' sql clause for DataTable. 
    /**//*
     * The implement detail refers to http://weblogs.asp.net/eporter/archive/2005/02/10/370548.aspx. Many thanks to Erik Porter.
     * NOTE:The .NET 2.0's DataView provider a ToTable method that will build a DataTable based off of the current DataView and 
     *      also allow you to specify which columns you want in the DataTable as all as being able to say Distinct rows only.
     *      So, recommends to consume the override method directly as following:
     *      <example>
     *      DataTable srcTable;
     *      // 
     *      DataView srcView = srcTable.DefaultView;
     *      DataTable dstTable = srcView.ToTable("NewTableName", true, "ColumnName1", "ColumnName2", "ColumnNameN");
     *      </example>
    */

    private static DataTable SelectDistinct(DataTable sourceTable, string newTableName, bool distinct, params string[] columnNames)
    {
        object[] lastValues;
        DataTable newTable;
        DataRow[] orderedRows;

        if (columnNames == null || columnNames.Length == 0)
            throw new ArgumentNullException("columnNames");

        lastValues = new object[columnNames.Length];
        newTable = new DataTable();

        for (int i = 0; i < columnNames.Length; i++) {            
            DataColumn column = sourceTable.Columns[columnNames[i]];
            if (column == null) {
                throw new ArgumentException(
                    String.Format("The specified column (columnNames[{0}] with value of '{1}') is not in the sourceTable.", i.ToString(), columnNames[i]),
                    "columnNames");
            }
            newTable.Columns.Add(columnNames[i], column.DataType);
        }

        orderedRows = sourceTable.Select("", string.Join(", ", columnNames));

        if (distinct) {
            foreach (DataRow row in orderedRows) {
                if (!ColumnValuesAreEqual(lastValues, row, columnNames)) {
                    newTable.Rows.Add(CreateRowClone(row, newTable.NewRow(), columnNames));

                    SetLastValues(lastValues, row, columnNames);
                }
            }
        }
        else {
            foreach (DataRow row in orderedRows) {
                newTable.Rows.Add(CreateRowClone(row, newTable.NewRow(), columnNames));
            }
        }
        return newTable;
    }

    private static bool ColumnValuesAreEqual(object[] lastValues, DataRow currentRow, string[] columnNames)
    {
        bool areEqual = true;

        for (int i = 0; i < columnNames.Length; i++) {
            if (lastValues[i] == null || !lastValues[i].Equals(currentRow[columnNames[i]])) {
                areEqual = false;
                break;
            }
        }

        return areEqual;
    }

    private static DataRow CreateRowClone(DataRow sourceRow, DataRow newRow, string[] columnNames)
    {
        foreach (string field in columnNames) {
            newRow[field] = sourceRow[field];
        }

        return newRow;
    }

    private static void SetLastValues(object[] lastValues, DataRow sourceRow, string[] columnNames)
    {
        for (int i = 0; i < columnNames.Length; i++) {
            lastValues[i] = sourceRow[columnNames[i]];
        }
    }

    #endregion

说明:由于朋友要求是在 1.1 环境下,所以只有自己写SelectDistinct,只有用DataGrid演示了^_^

源码:
下载

交叉表的简单实现2:使用前端程序实现相关推荐

  1. 生成交叉表的简单通用存储过程

    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_qry]') and OBJECTPROPERTY(id ...

  2. Jasperreport_6.18的吐血记录四之分组交叉表

    承接上篇 第三章主要说了交叉表的简单使用以及列出了在交叉表制作过程中可能会遇到的实际场景,还有就是实际场景中出现的一些坑,为了方便演示所以案例数据比较简单,希望小伙伴们认真阅读,细节很多,各位伙伴多注 ...

  3. 交叉表查询(TRANSFORM)

    sql中没有类似ACCESS的标准交叉表处理功能.      使用CASE和GROUP子句才是正确的选择(sql联机帮助也是这样说的,官方推荐) 动态列的问题,可以通过动态sql语句实现. --参考: ...

  4. Java实现交叉表_Sql交叉表简单实现 | 学步园

    最近碰到一需求,是酱紫的: 一个销售商品表, 每年每月每天都卖出N种不同种类的商品, 最后要统计每月每种商品的销售额. 或每年的, 在此我模拟创建了一个简单的表, 主要说明经验和大家一块分享, 若发现 ...

  5. 如何生成表_SPSS简单操作 | 如何生成交叉表?

    (。・∀・)嗨!学堂君,今天讲什么内容呢? 今天要分享的是如何生成交叉表. 什么是交叉表呀? 如果说交叉表可能大家会比较陌生,但是说到列联表可能就会比较熟悉.交叉表是我们在操作SPSS进行列联表分析时 ...

  6. cognos-rs用下拉列表来控制交叉表的显示内容

    cognos-rs用下拉列表来控制交叉表的显示内容 功能:用下拉列表来控制交叉表的显示内容,主要控件是:值提示.提交按钮: 如上图,当选择订单笔数时,交叉表表角显示为[订单笔数]-交叉表内容显示为订单 ...

  7. Quick BI 3.0 - 强大的多维分析表格:交叉表

    写在开头 对于普通的表格展示数据,相信大家都非常熟悉了,今天给大家介绍的是BI领域的分析利器-交叉表,这个在BI分析场景中使用占比最多的分析利器.通过交叉表对数据的承载和管理,用户可以一目了然地分析出 ...

  8. pandas高级处理-交叉表与透视表

    pandas高级处理-交叉表与透视表 1 交叉表与透视表什么作用  [就是探究两列数据之间的关系] 探究股票的涨跌与星期几有关? 以下图当中表示,week代表星期几,1,0代表这一天股票的涨跌幅是好还 ...

  9. python做数据透视表_Python--数据透视表和交叉表、数据读取

    数据 透视表 and 交叉表 先看数据是什么样的 ... #date dati = ['2019-11-01','2019-11-02','2019-11-03']*3rng=pd.to_dateti ...

最新文章

  1. 原理+代码实战 | 双目视觉中的极线校正
  2. 语音合成模块 文本转TTS 真人发音 SYN6288
  3. python ioc di_Spring介绍,IOC(控制反转),DI(依赖注入)介绍及两种注入方法
  4. 字符编码笔记:ASCII,Unicode和UTF-8
  5. 交通预测论文笔记:Spatio-Temporal Graph Convolutional Networks: A Deep Learning Frameworkfor Traffic Forecast
  6. java提高篇之数组(2)
  7. 网易云信与林鹿科技联手推出云对讲服务
  8. Flink SQL Client注册Python UDF完整流程
  9. sql 删除字段中下划线_SQL基础教程知识点总结
  10. java asynchronize_Java 中synchronize函数的实例详解
  11. Qt 插件学习(一)
  12. 人工神经网络到底能干什么?到底在干什么?
  13. 基于 Flink 构建全场景多维度实时计算数仓
  14. 模型实践 | Alphafold 蛋白质结构预测
  15. EfficientNet网络结构详解
  16. 系统测试和验收测试的区别
  17. b哩b哩视频弹幕爬虫程序(python)
  18. Java微服务实战项目推荐
  19. mysql 人名_jsp为什么按人名查询mysql结果不显示在页面上?可以
  20. 智能巡检机器人打造无人值守智慧车站

热门文章

  1. OpenERP里面继承的用法
  2. supervisord+supervisorclusterctl+supervisord-monit
  3. 敏捷开发中Scrum方法
  4. ASP.NET 2.0 X64的奇怪问题
  5. Go语言学习笔记 - PART11 - 面向对象
  6. Confluence 6 配置 HTTP 超时设置
  7. 微服务常见安全认证方案Session token cookie跨域
  8. mysql开启skip-name-resolve 导致root@127.0.0.1(localhost)访问引发的ERROR 1045 (28000)错误解决方案...
  9. 简单说一下,你对CPU缓存的了解?
  10. DEDE列表缩图中 给缩图添加alt锚文本信息的方法