C#实现Pivot(Cross Table)的一段代码和例子



None.gif public   static  DataTable Pivot(IDataReader dataValues,  string  keyColumn,  string  pivotNameColumn,  string  pivotValueColumn) 
ExpandedBlockStart.gifContractedBlock.gif  
dot.gif
InBlock.gif   DataTable tmp 
= new DataTable(); 
InBlock.gif   DataRow r; 
InBlock.gif   
int i, pValIndex, pNameIndex; 
InBlock.gif   
string s; 
InBlock.gif
InBlock.gif   
// Add non-pivot columns to the data table: 
InBlock.gif
   pValIndex = dataValues.GetOrdinal(pivotValueColumn); 
InBlock.gif   pNameIndex 
= dataValues.GetOrdinal(pivotNameColumn); 
InBlock.gif
InBlock.gif   
// Loop through columns 
InBlock.gif
   for (i = 0; i <= dataValues.FieldCount - 1; i++
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif
InBlock.gif    
if (i != pValIndex && i != pNameIndex) 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif     DataColumn dc 
= new DataColumn(dataValues.GetName (i), dataValues.GetFieldType(i)); 
InBlock.gif     tmp.Columns.Add(dc); 
InBlock.gif
InBlock.gif     
// Add key column 
InBlock.gif
     if (dc.ColumnName == keyColumn) 
ExpandedSubBlockStart.gifContractedSubBlock.gif      tmp.PrimaryKey 
= new DataColumn[] dot.gif{ dc }
ExpandedSubBlockEnd.gif    }
 
ExpandedSubBlockEnd.gif   }
 
InBlock.gif
InBlock.gif   
// now, fill up the table with the data 
InBlock.gif
   while (dataValues.Read()) 
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif
InBlock.gif    
// assign the pivot values to the proper column; add new columns if needed: 
InBlock.gif
    s = dataValues[pNameIndex].ToString(); 
InBlock.gif    
if (!tmp.Columns.Contains(s)) 
InBlock.gif     tmp.Columns.Add(s, dataValues.GetFieldType(pValIndex)); 
InBlock.gif
InBlock.gif    
// Create new row after adding any additional columns 
InBlock.gif
    r = tmp.NewRow(); 
InBlock.gif
InBlock.gif    
// Add pivot value 
InBlock.gif
    r[s] = dataValues[pValIndex]; 
InBlock.gif
InBlock.gif    
// Add all non-pivot column values to the new row: 
InBlock.gif
    for (i = 0; i <= dataValues.FieldCount - 3; i++
InBlock.gif     r[i] 
= dataValues[tmp.Columns[i].ColumnName]; 
InBlock.gif
InBlock.gif    
// Look for key 
InBlock.gif
    DataRow rowFound = tmp.Rows.Find(r[keyColumn]); 
InBlock.gif
InBlock.gif    
// Add new record if not found 
InBlock.gif
    if (null == rowFound) 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif     tmp.Rows.Add(r); 
ExpandedSubBlockEnd.gif    }
 
InBlock.gif    
else // Key already exists .. just update it 
ExpandedSubBlockStart.gifContractedSubBlock.gif
    dot.gif
InBlock.gif     rowFound[s] 
= dataValues[pValIndex]; 
ExpandedSubBlockEnd.gif    }
 
ExpandedSubBlockEnd.gif   }
 
InBlock.gif   
// Close the DataReader 
InBlock.gif
   dataValues.Close(); 
InBlock.gif   
// and that's it! 
InBlock.gif
   return tmp; 
ExpandedBlockEnd.gif  }
 
None.gif
None.gif
dataValues -- this is any open DataReader object, ready to be transformed and pivoted into a DataTable.  As mentioned, it should be fully grouped, aggregated, sorted and ready to go.  要处理的DataReader keyColumn -- This is the column in the DataReader which serves to identify each row.  In the previous example, this would be CustomerID.  Your DataReader's recordset should be grouped and sorted by this column as well. X轴字段 pivotNameColumn -- This is the column in the DataReader that contains the values you'd like to transform from rows into columns.   In the example, this would be ProductName. Y轴字段 pivotValueColumn -- This is the column that in the DataReader that contains the values to pivot into the appropriate columns.  For our example, it would be Qty, which has been defined in the SELECT statement as SUM(Qty). 数据区字段

例子:
None.gif private   void  Sample()
None.gif
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
// call this from a form dot.gif.
InBlock.gif

InBlock.gif
InBlock.gif             SqlConnection conn;
InBlock.gif
InBlock.gif             SqlCommand com;
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif             DataGrid dg 
= new DataGrid();
InBlock.gif
InBlock.gif             dg.Parent 
= this;
InBlock.gif
InBlock.gif             dg.Dock 
= DockStyle.Fill;
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif            String SQL 
= 
InBlock.gif
InBlock.gif                 
"select o.customerID, c.CompanyName, p.productName, sum(od.quantity) as Qty " +
InBlock.gif
InBlock.gif                 
" from orders o " +
InBlock.gif
InBlock.gif                 
" inner join [order details] od on o.orderID = od.orderID " +
InBlock.gif
InBlock.gif                 
" inner join Products p on od.ProductID = p.ProductID " +
InBlock.gif
InBlock.gif                 
" inner join Customers c  on o.CustomerID = c.CustomerID " +
InBlock.gif
InBlock.gif                 
" group by o.customerID, c.CompanyName, p.ProductName " +
InBlock.gif
InBlock.gif                
" order by o.customerID ";
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif             conn 
= new SqlConnection( "Server=(local);Database=Northwind;uid=xx;pwd=xx");
InBlock.gif
InBlock.gif             conn.Open();
InBlock.gif
InBlock.gif             com 
= new SqlCommand(SQL, conn);
InBlock.gif
InBlock.gif             
try
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif             
dot.gif{
InBlock.gif
InBlock.gif                 dg.DataSource 
= Pivot(com.ExecuteReader(),"CustomerID""ProductName","Qty");
InBlock.gif
ExpandedSubBlockEnd.gif             }
 
InBlock.gif
InBlock.gif             
catch (SqlException ex)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif             
dot.gif{
InBlock.gif
InBlock.gif                 MessageBox.Show(ex.Message);
InBlock.gif
ExpandedSubBlockEnd.gif             }

InBlock.gif
ExpandedBlockEnd.gif        }
 
None.gif 
None.gif

转载自: http://weblogs.sqlteam.com/jeffs/archive/2005/05/11/5101.aspx
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值