2015-09-04 92 views
0

我正在使用C#ConoleApplication。計算datacolumn中每個distict項的出現次數

我有我帶入Datatable的ODBC DSN連接。 第一列是「賬號#」。

例如:

賬號#------------ |

AA1 ------------------- |

AA1 ------------------- |

AA2 ------------------- |

AA3 ------------------- |

AA1 ------------------- |

AA4 ------------------- |

AA2 ------------------- |

我想解決如何給出以下結果。 我認爲這將被彙總成一個新的數據表,但我不能做任何代碼工作,我已經嘗試過。

賬號#------------ | OCCURENCES

AA1 ------------------- | 3

AA2 ------------------ - | 2

AA3 ------------------- | 1

AA4 ---------------- --- | 1

請問我該怎麼做?

+0

發生次數有2個';' – samjudson

回答

6

您可以使用Linq-To-DataTableEnumerable.GroupBy

var accountGroups = table.AsEnumerable() 
    .GroupBy(row => row.Field<String>("Account#")) 
    .Select(grp => new { Account = grp.Key, Count = grp.Count() }); 

如果你需要一個新的DataTable

var tblAccCounts = new DataTable(); 
tblAccCounts.Columns.Add("Account#"); 
tblAccCounts.Columns.Add("Count", typeof(int)); 

foreach(var grp in accountGroups) 
    tblAccCounts.Rows.Add(grp.Account, grp.Count); 
+0

向上爲匿名類型列表 –

+0

謝謝,這工作完美。 – Infost

+0

這真是太棒了,我已經使用了很多年了,但是我現在遇到了麻煩,因爲源代碼包含一些較高和較低的混合數據。這段代碼不會忽略大小寫。我如何做到這一點,或者我可以做到全部大寫。 – Infost

0

沒有測試,但使用LINQ它會讓你的生活更輕鬆

using System.Linq; 

dynamic amounts = dataTable 
    .AsQueryable() 
    .GroupBy(item => item.AccountNumber) 
    .Select(list => new{ AccountNumber: list.Key, Amount: list.Count() }).ToList(); 
-1

您正在使用SqlServer?如果是的話,你可以這樣做在bd上:

SELECT Account#, Count(*) FROM [Table] GROUP BY Account# 
+0

他指出他正在使用c# – maksymiuk

+0

是的,但他從一些數據庫中獲取數據,如果我沒有弄錯,以及如果即時通訊從數據庫ID獲取數據而不是計數/組/排序在數據庫然後在c# – JoaoFSA

0

也許這會工作。剛剛在我的數據庫上試了一下。

select account,count(account)from table group by account;

1

對於LINQ,DataTable有點奇怪,但可以完成。關鍵是轉換由DataTable.Rows返回的DataRowCollection。

var results = DataTable.Rows 
    .Cast<DataRow>() 
    .GroupBy(row => row.Field<string>(0)) 
    .Select(g => new { Account = g.Key, Occurrences = g.Count()}); 

將結果導入新的DataTable有點複雜,因爲您需要手動創建表。

DataTable newTable = new DataTable(); 
newTable.Columns.Add(new DataColumn("Account#", typeof(string))); 
newTable.Columns.Add(new DataColumn("Occurrences", typeof(int))); 

foreach(var result in results) 
{ 
    var row = newTable.Rows.NewRow(); 
    row[0] = result.Account; 
    row[1] = result.Occurrences; 
    newTable.Rows.Add(row); 
} 

編輯:Tim的解決方案也適用:)

0

你可以試試這個:

class Program 
    { 
     static void Main(string[] args) 
     { 
      testClass tc = new testClass(); 
      DataTable dt = tc.getTestData(); 

      for(int i = 0; i < dt.Rows.Count; i++) 
      { 
       Console.WriteLine("Account No {0} Occurence {1}", dt.Rows[i]["ACCNO"].ToString(), dt.Rows[i]["Occurence"].ToString()); 
      } 
     } 
    } 

    class testClass 
    { 
     public string AccountNo { get; set; } 

     private SqlConnection Conn; 

     private void TestConnect() 
     { 
      string strConn = "Data source = .\\SQLEXPRESS2012; Initial catalog = TEST; Integrated security = SSPI;"; 
      Conn = new SqlConnection(strConn); 
     } 

     public DataTable getTestData() 
     { 
      TestConnect(); 
      string cmdStr = "SELECT ACCNO, COUNT(XYZ.ACCNO) AS 'Occurence' FROM XYZ GROUP BY ACCNO;"; 
      SqlCommand cmd = new SqlCommand(cmdStr, Conn); 
      SqlDataAdapter sda = new SqlDataAdapter(cmd); 
      DataTable dt = new DataTable(); 
      try 
      { 
       Conn.Open(); 
       sda.Fill(dt); 
      } 
      catch (SqlException se) 
      { 
       Console.WriteLine("Error occured {0}", se.ToString()); 
      } 
      finally 
      { 
       Conn.Close(); 
      } 

      return dt; 
     } 
    } 
0

簡單和可靠的解決方案

我覺得這是什麼你自找的。

示例代碼在這個例子中

我不知道你的源數據表叫,所以我把它叫做SourceDataTable

// Create Results DataTable 

DataTable ResultsDataTable = new DataTable(); 
ResultsDataTable.Columns.Add("Account#"); // Columns default to System.string 
ResultsDataTable.Columns.Add("Occurances", Type.GetType("System.Int32")); 

ResultsDataTable.AcceptChanges(); //This asserts any changes to your table structure. 

// Populate Results DataTable 

foreach (DataRow SourceDataRow in SourceDataTable.Rows) 
{ 
    string AccountNumber = SourceDataRow["Account#"].ToString(); 

    bool IsPresent = false; 

    foreach(DataRow ResultsDataRow in ResultsDataTable.Rows) 
    { 
     if(ResultsDataRow["Account#"].ToString() == AccountNumber) 
     { 
      ResultsDataRow["Occurances"] = ((int)ResultsDataRow["Occurances"]) + 1; //Row exists for this account number, so increment the occurances value 

      IsPresent = true; 

      break; 

     } 

    } 

    if (!IsPresent) 
    { 
     // There isn't a row for this Account number, so create one and set it to one. 

     DataRow NewResultsRow = ResultsDataTable.NewRow(); 

     NewResultsRow["Account#"] = AccountNumber; 

     NewResultsRow["Occurances"] = 1; 

     ResultsDataTable.Rows.Add(NewResultsRow); 

     ResultsDataTable.AcceptChanges(); 

    } 

} 

ResultsDataTable.AcceptChanges(); 

注意事項。

同樣,我創建了一個名爲ResultsDataTable的結果數據表。

這是關於快兩倍,最近的LINQ相當於

這涵蓋了大部分的常用方法來操作數據表,所以它應該站在你非常有利解決未來對自己的類似的問題。

我希望它有幫助,祝你好運。