行列转换
一.概述
1、 行转列
例如将下表(RowToColumn)
|
Student |
Course |
Score |
|
李四 |
语文 |
78 |
|
李四 |
数学 |
66 |
|
张珊 |
语文 |
67 |
|
张珊 |
数学 |
79 |
转成(ColumnToRow)
|
Student |
语文 |
数学 |
|
李四 |
78 |
66 |
|
张珊 |
67 |
79 |
2.列转行:上述过程反过来
二.Sqlserver中的两种转换方式
- 行转列
[1] Pivot
语法:
|
Table_Source Pivot ( 聚合函数(value_column) For pivot_column in (<column_list>) ) |
例:
select Student,[语文],[数学] from RowToColumn pivot ( max(score) for Course in ([语文],[数学]) ) tb
查询结果如上表ColumnToRow
[2] Case when
例:
select student,max(case Course when '语文' then Score else 0 end) as [语文]
,max(case Course when '数学' then Score else 0 end) as [数学] from RowToColumn group by student
查询结果如上表ColumnToRow
- 列转行
[1] UnPivot
语法:
|
Table_Source UnPivot( value_column for pivot_column in(<column_list>) ) |
例:
select student ,Course,Score from ColumnToRow unpivot (Score for Course in([语文],[数学])) t
[2] Union
例:
select * from(
select student ,Course='语文',Score=[语文] from ColumnToRow
union
select student ,Course='数学',Score=[数学] from ColumnToRow
) t
三.在C#中实现行列转换
- 行转列
/// <summary> /// 行转列 /// </summary> /// <param name="sourseDT">源datatable</param> /// <param name="column">作为转换依据的列,即将此列中的行值转换为列</param> /// <param name="Value">除column外的另一列,新列的列值将从此列获取</param> /// <returns></returns> public DataTable RowToColumn(DataTable sourseDT, string column, string ValueCol) { string sortCol = ""; string[] sortCols = new string[sourseDT.Columns.Count]; DataTable result = new DataTable(); DataTable dtTemp = new DataTable(); string groupCol = ""; int groupColNum = 0; foreach (DataColumn item in sourseDT.Columns)//添加除column、ValueCol外原来的列 { if (item.Caption == column || item.Caption == ValueCol) continue; result.Columns.Add(item.Caption); if (groupCol.Length > 0) groupCol += ","; groupCol += item.Caption; groupColNum++;//标记除column、ValueCol外原来的列 } sortCol = groupCol + "," + column + "," + ValueCol; sortCols = sortCol.Split(','); sourseDT = sourseDT.DefaultView.ToTable(false, sortCols);//重新排序sourseDT:除column、ValueCol外原来的列排在前面 dtTemp = sourseDT.DefaultView.ToTable(true, column);//获取column列无重复数据 foreach (DataRow item in dtTemp.Rows)//column列无重复列值全转为列 { result.Columns.Add(item[column].ToString()); } dtTemp = sourseDT.DefaultView.ToTable(true, groupCol.Split(','));//依据groupCol,得到分组分组依据行 DataTable dtTemp1 = new DataTable(); foreach (DataRow item in dtTemp.Rows) { object[] newRow = new object[result.Columns.Count]; string tempfilter=""; foreach (DataColumn item1 in dtTemp.Columns)//根据dtTemp中的一条记录,从sourseDT筛选出一组数据 { if (tempfilter.Length > 0) tempfilter += " and "; tempfilter+=item1.ColumnName+"='"+item[item1].ToString()+"'"; } sourseDT.DefaultView.RowFilter=tempfilter; dtTemp1 = sourseDT.DefaultView.ToTable();//筛选结果,新表的一行记录将从这个dtTemp1里取 foreach (DataRow row in dtTemp1.Rows) { for (int i = 0; i < result.Columns.Count; i++) { if (i < groupColNum) { newRow[i] = row[i]; } else if (row[column].ToString() == result.Columns[i].ColumnName) { newRow[i] = row[ValueCol].ToString(); break; } } } result.Rows.Add(newRow); } return result; }
2.列转行
/// <summary> /// 列转行 /// </summary> /// <param name="sourseDT">源datatable</param> /// <param name="columns">将要被转成行的列</param> /// <param name="colName">新表中存放的列名的列</param> /// <param name="colValueName">新表中存放的列值的列</param> /// <returns></returns> public DataTable ColumnToRow(DataTable sourseDT,string[] columns ,string colName,string colValueName) { DataTable result = new DataTable(); string sortCol = ""; string[] sortCols = new string[sourseDT.Columns.Count]; foreach (DataColumn item in sourseDT.Columns)//添加全部除columns列以外的列 { if (columns.Contains(item.ColumnName)) continue; result.Columns.Add(item.ColumnName); if (sortCol.Length > 0) sortCol += ","; sortCol += item.ColumnName; } sortCols = sortCol.Split(',').Union(columns).ToArray(); sourseDT = sourseDT.DefaultView.ToTable(false, sortCols); result.Columns.Add(colName); result.Columns.Add(colValueName); foreach (DataRow row in sourseDT.Rows) { object[] newRow = new object[result.Columns.Count]; for (int i=0;i<sourseDT.Columns.Count;i++) { if (!columns.Contains(sourseDT.Columns[i].ColumnName)) { newRow[i] = row[i]; } else { newRow[newRow.Length-2] = sourseDT.Columns[i].ColumnName;//存列名 newRow[newRow.Length-1] = row[i];//存列值 result.Rows.Add(newRow); } } } return result; }
浙公网安备 33010602011771号